Merged a bunch of 2.4 and 2.6 files that were mostly common.
3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ linux-2.4.26-xen-sparse/arch/xen/drivers/console/Makefile
3e5a4e656nfFISThfbyXQOA6HN6YHw linux-2.4.26-xen-sparse/arch/xen/drivers/dom0/Makefile
40420a6ebRqDjufoN1WSJvolEW2Wjw linux-2.4.26-xen-sparse/arch/xen/drivers/evtchn/Makefile
-40420a73Wou6JlsZDiu6YwjYomsm7A linux-2.4.26-xen-sparse/arch/xen/drivers/evtchn/evtchn.c
4083dc16-Kd5y9psK_yk161sme5j5Q linux-2.4.26-xen-sparse/arch/xen/drivers/netif/Makefile
4083dc16UmHXxS9g_UFVnkUpN-oP2Q linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/Makefile
405853f2wg7JXZJNltspMwOZJklxgw linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/Makefile
3e5a4e65lWzkiPXsZdzPt2RNnJGG1g linux-2.4.26-xen-sparse/arch/xen/kernel/Makefile
-4075806dE5mQwlVUf8-t3YXjiMMWDQ linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c
3e5a4e65_hqfuxtGG8IUy6wRM86Ecg linux-2.4.26-xen-sparse/arch/xen/kernel/entry.S
-3e5a4e65ibVQmwlOn0j3sVH_j_6hAg linux-2.4.26-xen-sparse/arch/xen/kernel/evtchn.c
3e5a4e65Hy_1iUvMTPsNqGNXd9uFpg linux-2.4.26-xen-sparse/arch/xen/kernel/head.S
3e5a4e65RMGcuA-HCn3-wNx3fFQwdg linux-2.4.26-xen-sparse/arch/xen/kernel/i386_ksyms.c
3e5a4e653U6cELGv528IxOLHvCq8iA linux-2.4.26-xen-sparse/arch/xen/kernel/irq.c
3e5a4e6637ZDk0BvFEC-aFQs599-ng linux-2.4.26-xen-sparse/arch/xen/lib/delay.c
3e5a4e66croVgpcJyJuF2ycQw0HuJw linux-2.4.26-xen-sparse/arch/xen/mm/Makefile
3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg linux-2.4.26-xen-sparse/arch/xen/mm/fault.c
-3e5a4e668SE9rixq4ahho9rNhLUUFQ linux-2.4.26-xen-sparse/arch/xen/mm/hypervisor.c
3e5a4e661gLzzff25pJooKIIWe7IWg linux-2.4.26-xen-sparse/arch/xen/mm/init.c
3f0bed43UUdQichXAiVNrjV-y2Kzcg linux-2.4.26-xen-sparse/arch/xen/mm/ioremap.c
3e5a4e66qRlSTcjafidMB6ulECADvg linux-2.4.26-xen-sparse/arch/xen/vmlinux.lds
40c9c0c1pPwYE3-4i-oI3ubUu7UgvQ linux-2.4.26-xen-sparse/drivers/scsi/aic7xxx/Makefile
3e5a4e669uzIE54VwucPYtGwXLAbzA linux-2.4.26-xen-sparse/fs/exec.c
3e5a4e66wbeCpsJgVf_U8Jde-CNcsA linux-2.4.26-xen-sparse/include/asm-xen/bugs.h
-4048c0ddxnIa2GpBAVR-mY6mNSdeJg linux-2.4.26-xen-sparse/include/asm-xen/ctrl_if.h
3e5a4e66HdSkvIV6SJ1evG_xmTmXHA linux-2.4.26-xen-sparse/include/asm-xen/desc.h
-4048c0e0_P2wUTiT6UqgPhn0s7yFcA linux-2.4.26-xen-sparse/include/asm-xen/evtchn.h
3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw linux-2.4.26-xen-sparse/include/asm-xen/fixmap.h
406aeeaaQvl4RNtmd9hDEugBURbFpQ linux-2.4.26-xen-sparse/include/asm-xen/highmem.h
3e5a4e67YtcyDLQsShhCfQwPSELfvA linux-2.4.26-xen-sparse/include/asm-xen/hw_irq.h
-3e5a4e677VBavzM1UZIEcH1B-RlXMA linux-2.4.26-xen-sparse/include/asm-xen/hypervisor.h
4060044fVx7-tokvNLKBf_6qBB4lqQ linux-2.4.26-xen-sparse/include/asm-xen/io.h
3e5a4e673p7PEOyHFm3nHkYX6HQYBg linux-2.4.26-xen-sparse/include/asm-xen/irq.h
40d70c240tW7TWArl1VUgIFH2nVO1A linux-2.4.26-xen-sparse/include/asm-xen/keyboard.h
3e5a4e678ddsQOpbSiRdy1GRcDc9WA linux-2.4.26-xen-sparse/include/asm-xen/mmu_context.h
40d06e5b2YWInUX1Xv9amVANwd_2Xg linux-2.4.26-xen-sparse/include/asm-xen/module.h
3f8707e7ZmZ6TxyX0ZUEfvhA2Pb_xQ linux-2.4.26-xen-sparse/include/asm-xen/msr.h
-3e7270deQqtGPSnFxcW4AvJZuTUWfg linux-2.4.26-xen-sparse/include/asm-xen/multicall.h
3e5a4e67mnQfh-R8KcQCaVo2Oho6yg linux-2.4.26-xen-sparse/include/asm-xen/page.h
409ba2e7ZfV5hqTvIzxLtpClnxtIzg linux-2.4.26-xen-sparse/include/asm-xen/pci.h
3e5a4e67uTYU5oEnIDjxuaez8njjqg linux-2.4.26-xen-sparse/include/asm-xen/pgalloc.h
3e5a4e67X7JyupgdYkgDX19Huj2sAw linux-2.4.26-xen-sparse/include/asm-xen/pgtable-2level.h
3e5a4e67gr4NLGtQ5CvSLimMYZlkOA linux-2.4.26-xen-sparse/include/asm-xen/pgtable.h
-3f108af1qNv8DVSGPv4zpqIU1txCkg linux-2.4.26-xen-sparse/include/asm-xen/proc_cmd.h
3e5a4e676uK4xErTBDH6XJREn9LSyg linux-2.4.26-xen-sparse/include/asm-xen/processor.h
3e5a4e67AJPjW-zL7p-xWuA6IVeH1g linux-2.4.26-xen-sparse/include/asm-xen/ptrace.h
3e5a4e68uJz-xI0IBVMD7xRLQKJDFg linux-2.4.26-xen-sparse/include/asm-xen/segment.h
3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA linux-2.4.26-xen-sparse/include/asm-xen/smp.h
-3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.4.26-xen-sparse/include/asm-xen/suspend.h
4062f7e2PzFOUGT0PaE7A0VprTU3JQ linux-2.4.26-xen-sparse/include/asm-xen/synch_bitops.h
3e5a4e68mTr0zcp9SXDbnd-XLrrfxw linux-2.4.26-xen-sparse/include/asm-xen/system.h
3f1056a9L_kqHcFheV00KbKBzv9j5w linux-2.4.26-xen-sparse/include/asm-xen/vga.h
40f56238rXVTJQKbBuXXLH52qEArcg linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/Makefile
40f562385s4lr6Zg92gExe7UQ4A76Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/cpu/common.c
40f56238XDtHSijkAFlbv1PT8Bhw_Q linux-2.6.7-xen-sparse/arch/xen/i386/kernel/entry.S
-40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.7-xen-sparse/arch/xen/i386/kernel/evtchn.c
40f56238bnvciAuyzAiMkdzGErYt1A linux-2.6.7-xen-sparse/arch/xen/i386/kernel/head.S
40f58a0d31M2EkuPbG94ns_nOi0PVA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c
40faa751_zbZlAmLyQgCXdYekVFdWA linux-2.6.7-xen-sparse/arch/xen/i386/kernel/ioport.c
40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.7-xen-sparse/arch/xen/kernel/Makefile
40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.7-xen-sparse/arch/xen/kernel/ctrl_if.c
40f56239pYRq5yshPTkv3ujXKc8K6g linux-2.6.7-xen-sparse/arch/xen/kernel/empty.c
+40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.7-xen-sparse/arch/xen/kernel/evtchn.c
40f56239sFcjHiIRmnObRIDF-zaeKQ linux-2.6.7-xen-sparse/arch/xen/kernel/process.c
40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.7-xen-sparse/arch/xen/kernel/reboot.c
3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.7-xen-sparse/arch/xen/kernel/xen_proc.c
4107adf1E5O4ztGHNGMzCCNhcvqNow linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/dma-mapping.h
40f5623anSzpuEHgiNmQ56fIRfCoaQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/e820.h
40f5623akIoBsQ3KxSB2kufkbgONXQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/fixmap.h
-40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/hypervisor.h
40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/io.h
40f5623am9BzluYFuV6EQfTd-so3dA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/do_timer.h
40f5623adZQ1IZGPxbDXONjyZGYuTA linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/mach-xen/io_ports.h
40f5623bxUbeGjkRrjDguCy_Gm8RLw linux-2.6.7-xen-sparse/include/asm-xen/asm-i386/xor.h
40f5623bYNP7tHE2zX6YQxp9Zq2utQ linux-2.6.7-xen-sparse/include/asm-xen/ctrl_if.h
40f5623b3Eqs8pAc5WpPX8_jTzV2qw linux-2.6.7-xen-sparse/include/asm-xen/evtchn.h
+40f5623aGPlsm0u1LTO-NVZ6AGzNRQ linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h
40f5623cndVUFlkxpf7Lfx7xu8madQ linux-2.6.7-xen-sparse/include/asm-xen/multicall.h
3f108af1ylCIm82H052FVTfXACBHrw linux-2.6.7-xen-sparse/include/asm-xen/proc_cmd.h
-40f5623cBiQhPHILVLrl3xa6bDBaRg linux-2.6.7-xen-sparse/include/asm-xen/xen.h
+3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ linux-2.6.7-xen-sparse/include/asm-xen/suspend.h
3f689063BoW-HWV3auUJ-OqXfcGArw linux-2.6.7-xen-sparse/include/asm-xen/xen_proc.h
40f56a0ddHCSs3501MY4hRf22tctOw linux-2.6.7-xen-sparse/mkbuildtree
410a94a4KT6I6X0LVc7djB39tRDp4g linux-2.6.7-xen-sparse/mm/page_alloc.c
LINUX_RELEASE ?= 2.4
LINUX_VER ?= $(shell ( /bin/ls -ld linux-$(LINUX_RELEASE).*-xen-sparse ) 2>/dev/null | \
sed -e 's!^.*linux-\(.\+\)-xen-sparse!\1!' )
-LINUX24_VER ?= $(shell ( /bin/ls -ld linux-2.4.*-xen-sparse ) 2>/dev/null | \
+LINUX26_VER ?= $(shell ( /bin/ls -ld linux-2.6.*-xen-sparse ) 2>/dev/null | \
sed -e 's!^.*linux-\(.\+\)-xen-sparse!\1!' )
LINUX_CONFIG_DIR ?= $(INSTALL_DIR)/boot
LINUX_SRC_PATH ?= .:..
rm -rf install/* patches $(LINUX_TREES) linux-$(LINUX_VER).tar.*
make-symlinks: delete-symlinks
- ln -sf linux-$(LINUX24_VER)-xen-sparse linux-xen-sparse
+ ln -sf linux-$(LINUX26_VER)-xen-sparse linux-xen-sparse
delete-symlinks:
$(RM) linux-xen-sparse
+++ /dev/null
-/******************************************************************************
- * evtchn.c
- *
- * Xenolinux driver for receiving and demuxing event-channel signals.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/major.h>
-#include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/stat.h>
-#include <linux/poll.h>
-#include <linux/irq.h>
-#include <asm/evtchn.h>
-
-/* NB. This must be shared amongst drivers if more things go in /dev/xen */
-static devfs_handle_t xen_dev_dir;
-
-/* Only one process may open /dev/xen/evtchn at any time. */
-static unsigned long evtchn_dev_inuse;
-
-/* Notification ring, accessed via /dev/xen/evtchn. */
-#define RING_SIZE 2048 /* 2048 16-bit entries */
-#define RING_MASK(_i) ((_i)&(RING_SIZE-1))
-static u16 *ring;
-static unsigned int ring_cons, ring_prod, ring_overflow;
-
-/* Processes wait on this queue via /dev/xen/evtchn when ring is empty. */
-static DECLARE_WAIT_QUEUE_HEAD(evtchn_wait);
-static struct fasync_struct *evtchn_async_queue;
-
-/* Which ports is user-space bound to? */
-static u32 bound_ports[32];
-
-static spinlock_t lock;
-
-void evtchn_device_upcall(int port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
-
- spin_lock(&lock);
-
- mask_evtchn(port);
- clear_evtchn(port);
-
- if ( ring != NULL )
- {
- if ( (ring_prod - ring_cons) < RING_SIZE )
- {
- ring[RING_MASK(ring_prod)] = (u16)port;
- if ( ring_cons == ring_prod++ )
- {
- wake_up_interruptible(&evtchn_wait);
- kill_fasync(&evtchn_async_queue, SIGIO, POLL_IN);
- }
- }
- else
- {
- ring_overflow = 1;
- }
- }
-
- spin_unlock(&lock);
-}
-
-static void __evtchn_reset_buffer_ring(void)
-{
- /* Initialise the ring to empty. Clear errors. */
- ring_cons = ring_prod = ring_overflow = 0;
-}
-
-static ssize_t evtchn_read(struct file *file, char *buf,
- size_t count, loff_t *ppos)
-{
- int rc;
- unsigned int c, p, bytes1 = 0, bytes2 = 0;
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&evtchn_wait, &wait);
-
- count &= ~1; /* even number of bytes */
-
- if ( count == 0 )
- {
- rc = 0;
- goto out;
- }
-
- if ( count > PAGE_SIZE )
- count = PAGE_SIZE;
-
- for ( ; ; )
- {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if ( (c = ring_cons) != (p = ring_prod) )
- break;
-
- if ( ring_overflow )
- {
- rc = -EFBIG;
- goto out;
- }
-
- if ( file->f_flags & O_NONBLOCK )
- {
- rc = -EAGAIN;
- goto out;
- }
-
- if ( signal_pending(current) )
- {
- rc = -ERESTARTSYS;
- goto out;
- }
-
- schedule();
- }
-
- /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
- if ( ((c ^ p) & RING_SIZE) != 0 )
- {
- bytes1 = (RING_SIZE - RING_MASK(c)) * sizeof(u16);
- bytes2 = RING_MASK(p) * sizeof(u16);
- }
- else
- {
- bytes1 = (p - c) * sizeof(u16);
- bytes2 = 0;
- }
-
- /* Truncate chunks according to caller's maximum byte count. */
- if ( bytes1 > count )
- {
- bytes1 = count;
- bytes2 = 0;
- }
- else if ( (bytes1 + bytes2) > count )
- {
- bytes2 = count - bytes1;
- }
-
- if ( copy_to_user(buf, &ring[RING_MASK(c)], bytes1) ||
- ((bytes2 != 0) && copy_to_user(&buf[bytes1], &ring[0], bytes2)) )
- {
- rc = -EFAULT;
- goto out;
- }
-
- ring_cons += (bytes1 + bytes2) / sizeof(u16);
-
- rc = bytes1 + bytes2;
-
- out:
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&evtchn_wait, &wait);
- return rc;
-}
-
-static ssize_t evtchn_write(struct file *file, const char *buf,
- size_t count, loff_t *ppos)
-{
- int rc, i;
- u16 *kbuf = (u16 *)get_free_page(GFP_KERNEL);
-
- if ( kbuf == NULL )
- return -ENOMEM;
-
- count &= ~1; /* even number of bytes */
-
- if ( count == 0 )
- {
- rc = 0;
- goto out;
- }
-
- if ( count > PAGE_SIZE )
- count = PAGE_SIZE;
-
- if ( copy_from_user(kbuf, buf, count) != 0 )
- {
- rc = -EFAULT;
- goto out;
- }
-
- spin_lock_irq(&lock);
- for ( i = 0; i < (count/2); i++ )
- if ( test_bit(kbuf[i], &bound_ports[0]) )
- unmask_evtchn(kbuf[i]);
- spin_unlock_irq(&lock);
-
- rc = count;
-
- out:
- free_page((unsigned long)kbuf);
- return rc;
-}
-
-static int evtchn_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int rc = 0;
-
- spin_lock_irq(&lock);
-
- switch ( cmd )
- {
- case EVTCHN_RESET:
- __evtchn_reset_buffer_ring();
- break;
- case EVTCHN_BIND:
- if ( !test_and_set_bit(arg, &bound_ports[0]) )
- unmask_evtchn(arg);
- else
- rc = -EINVAL;
- break;
- case EVTCHN_UNBIND:
- if ( test_and_clear_bit(arg, &bound_ports[0]) )
- mask_evtchn(arg);
- else
- rc = -EINVAL;
- break;
- default:
- rc = -ENOSYS;
- break;
- }
-
- spin_unlock_irq(&lock);
-
- return rc;
-}
-
-static unsigned int evtchn_poll(struct file *file, poll_table *wait)
-{
- unsigned int mask = POLLOUT | POLLWRNORM;
- poll_wait(file, &evtchn_wait, wait);
- if ( ring_cons != ring_prod )
- mask |= POLLIN | POLLRDNORM;
- if ( ring_overflow )
- mask = POLLERR;
- return mask;
-}
-
-static int evtchn_fasync(int fd, struct file *filp, int on)
-{
- return fasync_helper(fd, filp, on, &evtchn_async_queue);
-}
-
-static int evtchn_open(struct inode *inode, struct file *filp)
-{
- u16 *_ring;
-
- if ( test_and_set_bit(0, &evtchn_dev_inuse) )
- return -EBUSY;
-
- /* Allocate outside locked region so that we can use GFP_KERNEL. */
- if ( (_ring = (u16 *)get_free_page(GFP_KERNEL)) == NULL )
- return -ENOMEM;
-
- spin_lock_irq(&lock);
- ring = _ring;
- __evtchn_reset_buffer_ring();
- spin_unlock_irq(&lock);
-
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static int evtchn_release(struct inode *inode, struct file *filp)
-{
- int i;
-
- spin_lock_irq(&lock);
- if ( ring != NULL )
- {
- free_page((unsigned long)ring);
- ring = NULL;
- }
- for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
- if ( test_and_clear_bit(i, &bound_ports[0]) )
- mask_evtchn(i);
- spin_unlock_irq(&lock);
-
- evtchn_dev_inuse = 0;
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static struct file_operations evtchn_fops = {
- owner: THIS_MODULE,
- read: evtchn_read,
- write: evtchn_write,
- ioctl: evtchn_ioctl,
- poll: evtchn_poll,
- fasync: evtchn_fasync,
- open: evtchn_open,
- release: evtchn_release
-};
-
-static struct miscdevice evtchn_miscdev = {
- minor: EVTCHN_MINOR,
- name: "evtchn",
- fops: &evtchn_fops
-};
-
-static int __init init_module(void)
-{
- devfs_handle_t symlink_handle;
- int err, pos;
- char link_dest[64];
-
- /* (DEVFS) create '/dev/misc/evtchn'. */
- err = misc_register(&evtchn_miscdev);
- if ( err != 0 )
- {
- printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
- return err;
- }
-
- /* (DEVFS) create directory '/dev/xen'. */
- xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL);
-
- /* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */
- pos = devfs_generate_path(evtchn_miscdev.devfs_handle,
- &link_dest[3],
- sizeof(link_dest) - 3);
- if ( pos >= 0 )
- strncpy(&link_dest[pos], "../", 3);
-
- /* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */
- (void)devfs_mk_symlink(xen_dev_dir,
- "evtchn",
- DEVFS_FL_DEFAULT,
- &link_dest[pos],
- &symlink_handle,
- NULL);
-
- /* (DEVFS) automatically destroy the symlink with its destination. */
- devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle);
-
- printk("Event-channel device installed.\n");
-
- return 0;
-}
-
-static void cleanup_module(void)
-{
- misc_deregister(&evtchn_miscdev);
-}
-
-module_init(init_module);
-module_exit(cleanup_module);
+++ /dev/null
-/******************************************************************************
- * ctrl_if.c
- *
- * Management functions for special interface to the domain controller.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <asm/ctrl_if.h>
-#include <asm/evtchn.h>
-
-#if 0
-#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
- __FILE__ , __LINE__ , ## _a )
-#else
-#define DPRINTK(_f, _a...) ((void)0)
-#endif
-
-/*
- * Only used by initial domain which must create its own control-interface
- * event channel. This value is picked up by the user-space domain controller
- * via an ioctl.
- */
-int initdom_ctrlif_domcontroller_port = -1;
-
-static int ctrl_if_evtchn;
-static int ctrl_if_irq;
-static spinlock_t ctrl_if_lock;
-
-static struct irqaction ctrl_if_irq_action;
-
-static CONTROL_RING_IDX ctrl_if_tx_resp_cons;
-static CONTROL_RING_IDX ctrl_if_rx_req_cons;
-
-/* Incoming message requests. */
- /* Primary message type -> message handler. */
-static ctrl_msg_handler_t ctrl_if_rxmsg_handler[256];
- /* Primary message type -> callback in process context? */
-static unsigned long ctrl_if_rxmsg_blocking_context[256/sizeof(unsigned long)];
- /* Is it late enough during bootstrap to use schedule_task()? */
-static int safe_to_schedule_task;
- /* Passed to schedule_task(). */
-static struct tq_struct ctrl_if_rxmsg_deferred_tq;
- /* Queue up messages to be handled in process context. */
-static ctrl_msg_t ctrl_if_rxmsg_deferred[CONTROL_RING_SIZE];
-static CONTROL_RING_IDX ctrl_if_rxmsg_deferred_prod;
-static CONTROL_RING_IDX ctrl_if_rxmsg_deferred_cons;
-
-/* Incoming message responses: message identifier -> message handler/id. */
-static struct {
- ctrl_msg_handler_t fn;
- unsigned long id;
-} ctrl_if_txmsg_id_mapping[CONTROL_RING_SIZE];
-
-static DECLARE_TASK_QUEUE(ctrl_if_tx_tq);
-static DECLARE_WAIT_QUEUE_HEAD(ctrl_if_tx_wait);
-static void __ctrl_if_tx_tasklet(unsigned long data);
-static DECLARE_TASKLET(ctrl_if_tx_tasklet, __ctrl_if_tx_tasklet, 0);
-
-static void __ctrl_if_rx_tasklet(unsigned long data);
-static DECLARE_TASKLET(ctrl_if_rx_tasklet, __ctrl_if_rx_tasklet, 0);
-
-#define get_ctrl_if() ((control_if_t *)((char *)HYPERVISOR_shared_info + 2048))
-#define TX_FULL(_c) \
- (((_c)->tx_req_prod - ctrl_if_tx_resp_cons) == CONTROL_RING_SIZE)
-
-static void ctrl_if_notify_controller(void)
-{
- notify_via_evtchn(ctrl_if_evtchn);
-}
-
-static void ctrl_if_rxmsg_default_handler(ctrl_msg_t *msg, unsigned long id)
-{
- msg->length = 0;
- ctrl_if_send_response(msg);
-}
-
-static void __ctrl_if_tx_tasklet(unsigned long data)
-{
- control_if_t *ctrl_if = get_ctrl_if();
- ctrl_msg_t *msg;
- int was_full = TX_FULL(ctrl_if);
-
- while ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod )
- {
- msg = &ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if_tx_resp_cons)];
-
- DPRINTK("Rx-Rsp %u/%u :: %d/%d\n",
- ctrl_if_tx_resp_cons,
- ctrl_if->tx_resp_prod,
- msg->type, msg->subtype);
-
- /* Execute the callback handler, if one was specified. */
- if ( msg->id != 0xFF )
- {
- (*ctrl_if_txmsg_id_mapping[msg->id].fn)(
- msg, ctrl_if_txmsg_id_mapping[msg->id].id);
- smp_mb(); /* Execute, /then/ free. */
- ctrl_if_txmsg_id_mapping[msg->id].fn = NULL;
- }
-
- /*
- * Step over the message in the ring /after/ finishing reading it. As
- * soon as the index is updated then the message may get blown away.
- */
- smp_mb();
- ctrl_if_tx_resp_cons++;
- }
-
- if ( was_full && !TX_FULL(ctrl_if) )
- {
- wake_up(&ctrl_if_tx_wait);
- run_task_queue(&ctrl_if_tx_tq);
- }
-}
-
-static void __ctrl_if_rxmsg_deferred(void *unused)
-{
- ctrl_msg_t *msg;
-
- while ( ctrl_if_rxmsg_deferred_cons != ctrl_if_rxmsg_deferred_prod )
- {
- msg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(
- ctrl_if_rxmsg_deferred_cons++)];
- (*ctrl_if_rxmsg_handler[msg->type])(msg, 0);
- }
-}
-
-static void __ctrl_if_rx_tasklet(unsigned long data)
-{
- control_if_t *ctrl_if = get_ctrl_if();
- ctrl_msg_t msg, *pmsg;
-
- while ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod )
- {
- pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)];
- memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg));
-
- DPRINTK("Rx-Req %u/%u :: %d/%d\n",
- ctrl_if_rx_req_cons-1,
- ctrl_if->rx_req_prod,
- msg.type, msg.subtype);
-
- if ( msg.length != 0 )
- memcpy(msg.msg, pmsg->msg, msg.length);
-
- if ( test_bit(msg.type, &ctrl_if_rxmsg_blocking_context) )
- {
- pmsg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(
- ctrl_if_rxmsg_deferred_prod++)];
- memcpy(pmsg, &msg, offsetof(ctrl_msg_t, msg) + msg.length);
- schedule_task(&ctrl_if_rxmsg_deferred_tq);
- }
- else
- {
- (*ctrl_if_rxmsg_handler[msg.type])(&msg, 0);
- }
- }
-}
-
-static void ctrl_if_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- control_if_t *ctrl_if = get_ctrl_if();
-
- if ( ctrl_if_tx_resp_cons != ctrl_if->tx_resp_prod )
- tasklet_schedule(&ctrl_if_tx_tasklet);
-
- if ( ctrl_if_rx_req_cons != ctrl_if->rx_req_prod )
- tasklet_schedule(&ctrl_if_rx_tasklet);
-}
-
-int ctrl_if_send_message_noblock(
- ctrl_msg_t *msg,
- ctrl_msg_handler_t hnd,
- unsigned long id)
-{
- control_if_t *ctrl_if = get_ctrl_if();
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&ctrl_if_lock, flags);
-
- if ( TX_FULL(ctrl_if) )
- {
- spin_unlock_irqrestore(&ctrl_if_lock, flags);
- return -EAGAIN;
- }
-
- msg->id = 0xFF;
- if ( hnd != NULL )
- {
- for ( i = 0; ctrl_if_txmsg_id_mapping[i].fn != NULL; i++ )
- continue;
- ctrl_if_txmsg_id_mapping[i].fn = hnd;
- ctrl_if_txmsg_id_mapping[i].id = id;
- msg->id = i;
- }
-
- DPRINTK("Tx-Req %u/%u :: %d/%d\n",
- ctrl_if->tx_req_prod,
- ctrl_if_tx_resp_cons,
- msg->type, msg->subtype);
-
- memcpy(&ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if->tx_req_prod)],
- msg, sizeof(*msg));
- wmb(); /* Write the message before letting the controller peek at it. */
- ctrl_if->tx_req_prod++;
-
- spin_unlock_irqrestore(&ctrl_if_lock, flags);
-
- ctrl_if_notify_controller();
-
- return 0;
-}
-
-int ctrl_if_send_message_block(
- ctrl_msg_t *msg,
- ctrl_msg_handler_t hnd,
- unsigned long id,
- long wait_state)
-{
- DECLARE_WAITQUEUE(wait, current);
- int rc;
-
- /* Fast path. */
- if ( (rc = ctrl_if_send_message_noblock(msg, hnd, id)) != -EAGAIN )
- return rc;
-
- add_wait_queue(&ctrl_if_tx_wait, &wait);
-
- for ( ; ; )
- {
- set_current_state(wait_state);
-
- if ( (rc = ctrl_if_send_message_noblock(msg, hnd, id)) != -EAGAIN )
- break;
-
- rc = -ERESTARTSYS;
- if ( signal_pending(current) && (wait_state == TASK_INTERRUPTIBLE) )
- break;
-
- schedule();
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&ctrl_if_tx_wait, &wait);
-
- return rc;
-}
-
-int ctrl_if_enqueue_space_callback(struct tq_struct *task)
-{
- control_if_t *ctrl_if = get_ctrl_if();
-
- /* Fast path. */
- if ( !TX_FULL(ctrl_if) )
- return 0;
-
- (void)queue_task(task, &ctrl_if_tx_tq);
-
- /*
- * We may race execution of the task queue, so return re-checked status. If
- * the task is not executed despite the ring being non-full then we will
- * certainly return 'not full'.
- */
- smp_mb();
- return TX_FULL(ctrl_if);
-}
-
-void ctrl_if_send_response(ctrl_msg_t *msg)
-{
- control_if_t *ctrl_if = get_ctrl_if();
- unsigned long flags;
- ctrl_msg_t *dmsg;
-
- /*
- * NB. The response may the original request message, modified in-place.
- * In this situation we may have src==dst, so no copying is required.
- */
- spin_lock_irqsave(&ctrl_if_lock, flags);
-
- DPRINTK("Tx-Rsp %u :: %d/%d\n",
- ctrl_if->rx_resp_prod,
- msg->type, msg->subtype);
-
- dmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if->rx_resp_prod)];
- if ( dmsg != msg )
- memcpy(dmsg, msg, sizeof(*msg));
-
- wmb(); /* Write the message before letting the controller peek at it. */
- ctrl_if->rx_resp_prod++;
-
- spin_unlock_irqrestore(&ctrl_if_lock, flags);
-
- ctrl_if_notify_controller();
-}
-
-int ctrl_if_register_receiver(
- u8 type,
- ctrl_msg_handler_t hnd,
- unsigned int flags)
-{
- unsigned long _flags;
- int inuse;
-
- spin_lock_irqsave(&ctrl_if_lock, _flags);
-
- inuse = (ctrl_if_rxmsg_handler[type] != ctrl_if_rxmsg_default_handler);
-
- if ( inuse )
- {
- printk(KERN_INFO "Receiver %p already established for control "
- "messages of type %d.\n", ctrl_if_rxmsg_handler[type], type);
- }
- else
- {
- ctrl_if_rxmsg_handler[type] = hnd;
- clear_bit(type, &ctrl_if_rxmsg_blocking_context);
- if ( flags == CALLBACK_IN_BLOCKING_CONTEXT )
- {
- set_bit(type, &ctrl_if_rxmsg_blocking_context);
- if ( !safe_to_schedule_task )
- BUG();
- }
- }
-
- spin_unlock_irqrestore(&ctrl_if_lock, _flags);
-
- return !inuse;
-}
-
-void ctrl_if_unregister_receiver(u8 type, ctrl_msg_handler_t hnd)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ctrl_if_lock, flags);
-
- if ( ctrl_if_rxmsg_handler[type] != hnd )
- printk(KERN_INFO "Receiver %p is not registered for control "
- "messages of type %d.\n", hnd, type);
- else
- ctrl_if_rxmsg_handler[type] = ctrl_if_rxmsg_default_handler;
-
- spin_unlock_irqrestore(&ctrl_if_lock, flags);
-
- /* Ensure that @hnd will not be executed after this function returns. */
- tasklet_unlock_wait(&ctrl_if_rx_tasklet);
-}
-
-void ctrl_if_suspend(void)
-{
- free_irq(ctrl_if_irq, NULL);
- unbind_evtchn_from_irq(ctrl_if_evtchn);
-}
-
-/** Reset the control interface progress pointers.
- * Marks the queues empty if 'clear' non-zero.
- */
-void ctrl_if_reset(int clear){
- control_if_t *ctrl_if = get_ctrl_if();
-
- if(clear){
- *ctrl_if = (control_if_t){};
- }
- ctrl_if_tx_resp_cons = ctrl_if->tx_resp_prod;
- ctrl_if_rx_req_cons = ctrl_if->rx_resp_prod;
-}
-
-void ctrl_if_resume(void)
-{
- if ( start_info.flags & SIF_INITDOMAIN )
- {
- /*
- * The initial domain must create its own domain-controller link.
- * The controller is probably not running at this point, but will
- * pick up its end of the event channel from
- */
- evtchn_op_t op;
- op.cmd = EVTCHNOP_bind_interdomain;
- op.u.bind_interdomain.dom1 = DOMID_SELF;
- op.u.bind_interdomain.dom2 = DOMID_SELF;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- BUG();
- start_info.domain_controller_evtchn = op.u.bind_interdomain.port1;
- initdom_ctrlif_domcontroller_port = op.u.bind_interdomain.port2;
- }
-
- ctrl_if_reset(0);
-
- ctrl_if_evtchn = start_info.domain_controller_evtchn;
- ctrl_if_irq = bind_evtchn_to_irq(ctrl_if_evtchn);
-
-#define SA_STATIC_ACTION 0x01000000 /* so that free_irq() doesn't do kfree() */
- memset(&ctrl_if_irq_action, 0, sizeof(ctrl_if_irq_action));
- ctrl_if_irq_action.handler = ctrl_if_interrupt;
- ctrl_if_irq_action.name = "ctrl-if";
- ctrl_if_irq_action.flags = SA_STATIC_ACTION;
- (void)setup_irq(ctrl_if_irq, &ctrl_if_irq_action);
-}
-
-void __init ctrl_if_init(void)
-{
- int i;
-
- for ( i = 0; i < 256; i++ )
- ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler;
- ctrl_if_rxmsg_deferred_tq.routine = __ctrl_if_rxmsg_deferred;
-
- spin_lock_init(&ctrl_if_lock);
-
- ctrl_if_reset(1);
- ctrl_if_resume();
-}
-
-
-/* This is called after it is safe to call schedule_task(). */
-static int __init ctrl_if_late_setup(void)
-{
- safe_to_schedule_task = 1;
- return 0;
-}
-__initcall(ctrl_if_late_setup);
-
-
-/*
- * !! The following are DANGEROUS FUNCTIONS !!
- * Use with care [for example, see xencons_force_flush()].
- */
-
-int ctrl_if_transmitter_empty(void)
-{
- return (get_ctrl_if()->tx_req_prod == ctrl_if_tx_resp_cons);
-}
-
-void ctrl_if_discard_responses(void)
-{
- ctrl_if_tx_resp_cons = get_ctrl_if()->tx_resp_prod;
-}
-
+++ /dev/null
-/******************************************************************************
- * evtchn.c
- *
- * Communication via Xen event channels.
- *
- * Copyright (c) 2002-2004, K A Fraser
- */
-
-#include <linux/config.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <asm/ptrace.h>
-#include <asm/synch_bitops.h>
-#include <asm/ctrl_if.h>
-#include <asm/hypervisor.h>
-#include <asm/hypervisor-ifs/event_channel.h>
-#include <asm/hypervisor-ifs/physdev.h>
-
-/*
- * This lock protects updates to the following mapping and reference-count
- * arrays. The lock does not need to be acquired to read the mapping tables.
- */
-static spinlock_t irq_mapping_update_lock;
-
-/* IRQ <-> event-channel mappings. */
-static int evtchn_to_irq[NR_EVENT_CHANNELS];
-static int irq_to_evtchn[NR_IRQS];
-
-/* IRQ <-> VIRQ mapping. */
-static int virq_to_irq[NR_VIRQS];
-
-/* Reference counts for bindings to IRQs. */
-static int irq_bindcount[NR_IRQS];
-
-/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
-
-/* Upcall to generic IRQ layer. */
-extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
-
-#define VALID_EVTCHN(_chn) ((_chn) != -1)
-
-void evtchn_do_upcall(struct pt_regs *regs)
-{
- unsigned long l1, l2;
- unsigned int l1i, l2i, port;
- int irq;
- unsigned long flags;
- shared_info_t *s = HYPERVISOR_shared_info;
-
- local_irq_save(flags);
-
- while ( s->vcpu_data[0].evtchn_upcall_pending )
- {
- s->vcpu_data[0].evtchn_upcall_pending = 0;
- /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
- l1 = xchg(&s->evtchn_pending_sel, 0);
- while ( (l1i = ffs(l1)) != 0 )
- {
- l1i--;
- l1 &= ~(1 << l1i);
-
- l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
- while ( (l2i = ffs(l2)) != 0 )
- {
- l2i--;
- l2 &= ~(1 << l2i);
-
- port = (l1i << 5) + l2i;
- if ( (irq = evtchn_to_irq[port]) != -1 )
- do_IRQ(irq, regs);
- else
- evtchn_device_upcall(port);
- }
- }
- }
-
- local_irq_restore(flags);
-}
-
-
-static int find_unbound_irq(void)
-{
- int irq;
-
- for ( irq = 0; irq < NR_IRQS; irq++ )
- if ( irq_bindcount[irq] == 0 )
- break;
-
- if ( irq == NR_IRQS )
- panic("No available IRQ to bind to: increase NR_IRQS!\n");
-
- return irq;
-}
-
-int bind_virq_to_irq(int virq)
-{
- evtchn_op_t op;
- int evtchn, irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = virq_to_irq[virq]) == -1 )
- {
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to bind virtual IRQ %d\n", virq);
- evtchn = op.u.bind_virq.port;
-
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- virq_to_irq[virq] = irq;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
-}
-
-void unbind_virq_from_irq(int virq)
-{
- evtchn_op_t op;
- int irq = virq_to_irq[virq];
- int evtchn = irq_to_evtchn[irq];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- op.cmd = EVTCHNOP_close;
- op.u.close.dom = DOMID_SELF;
- op.u.close.port = evtchn;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to unbind virtual IRQ %d\n", virq);
-
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- virq_to_irq[virq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-
-int bind_evtchn_to_irq(int evtchn)
-{
- int irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = evtchn_to_irq[evtchn]) == -1 )
- {
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
-}
-
-void unbind_evtchn_from_irq(int evtchn)
-{
- int irq = evtchn_to_irq[evtchn];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-
-
-/*
- * Interface to generic handling in irq.c
- */
-
-static unsigned int startup_dynirq(unsigned int irq)
-{
- unmask_evtchn(irq_to_evtchn[irq]);
- return 0;
-}
-
-static void shutdown_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void enable_dynirq(unsigned int irq)
-{
- unmask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void disable_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void ack_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
- clear_evtchn(irq_to_evtchn[irq]);
-}
-
-static void end_dynirq(unsigned int irq)
-{
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- unmask_evtchn(irq_to_evtchn[irq]);
-}
-
-static struct hw_interrupt_type dynirq_type = {
- "Dynamic-irq",
- startup_dynirq,
- shutdown_dynirq,
- enable_dynirq,
- disable_dynirq,
- ack_dynirq,
- end_dynirq,
- NULL
-};
-
-static inline void pirq_unmask_notify(int pirq)
-{
- physdev_op_t op;
- if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
- {
- op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
- (void)HYPERVISOR_physdev_op(&op);
- }
-}
-
-static inline void pirq_query_unmask(int pirq)
-{
- physdev_op_t op;
- op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
- op.u.irq_status_query.irq = pirq;
- (void)HYPERVISOR_physdev_op(&op);
- clear_bit(pirq, &pirq_needs_unmask_notify[0]);
- if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
- set_bit(pirq, &pirq_needs_unmask_notify[0]);
-}
-
-/*
- * On startup, if there is no action associated with the IRQ then we are
- * probing. In this case we should not share with others as it will confuse us.
- */
-#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
-
-static unsigned int startup_pirq(unsigned int irq)
-{
- evtchn_op_t op;
- int evtchn;
-
- op.cmd = EVTCHNOP_bind_pirq;
- op.u.bind_pirq.pirq = irq;
- /* NB. We are happy to share unless we are probing. */
- op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- {
- if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
- printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
- return 0;
- }
- evtchn = op.u.bind_pirq.port;
-
- pirq_query_unmask(irq_to_pirq(irq));
-
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
-
- return 0;
-}
-
-static void shutdown_pirq(unsigned int irq)
-{
- evtchn_op_t op;
- int evtchn = irq_to_evtchn[irq];
-
- if ( !VALID_EVTCHN(evtchn) )
- return;
-
- mask_evtchn(evtchn);
-
- op.cmd = EVTCHNOP_close;
- op.u.close.dom = DOMID_SELF;
- op.u.close.port = evtchn;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to unbind physical IRQ %d\n", irq);
-
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
-}
-
-static void enable_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
-}
-
-static void disable_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
-}
-
-static void ack_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
-}
-
-static void end_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- {
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
- }
-}
-
-static struct hw_interrupt_type pirq_type = {
- "Phys-irq",
- startup_pirq,
- shutdown_pirq,
- enable_pirq,
- disable_pirq,
- ack_pirq,
- end_pirq,
- NULL
-};
-
-static void misdirect_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- /* nothing */
-}
-
-static struct irqaction misdirect_action = {
- misdirect_interrupt,
- SA_INTERRUPT,
- 0,
- "misdirect",
- NULL,
- NULL
-};
-
-void irq_suspend(void)
-{
- int virq, irq, evtchn;
-
- /* Unbind VIRQs from event channels. */
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- {
- if ( (irq = virq_to_irq[virq]) == -1 )
- continue;
- evtchn = irq_to_evtchn[irq];
-
- /* Mark the event channel as unused in our table. */
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- /*
- * We should now be unbound from all event channels. Stale bindings to
- * PIRQs and/or inter-domain event channels will cause us to barf here.
- */
- for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
- if ( evtchn_to_irq[evtchn] != -1 )
- panic("Suspend attempted while bound to evtchn %d.\n", evtchn);
-}
-
-
-void irq_resume(void)
-{
- evtchn_op_t op;
- int virq, irq, evtchn;
-
- for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
- mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
-
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- {
- if ( (irq = virq_to_irq[virq]) == -1 )
- continue;
-
- /* Get a new binding from Xen. */
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to bind virtual IRQ %d\n", virq);
- evtchn = op.u.bind_virq.port;
-
- /* Record the new mapping. */
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- /* Ready for use. */
- unmask_evtchn(evtchn);
- }
-}
-
-void __init init_IRQ(void)
-{
- int i;
-
- spin_lock_init(&irq_mapping_update_lock);
-
- /* No VIRQ -> IRQ mappings. */
- for ( i = 0; i < NR_VIRQS; i++ )
- virq_to_irq[i] = -1;
-
- /* No event-channel -> IRQ mappings. */
- for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
- {
- evtchn_to_irq[i] = -1;
- mask_evtchn(i); /* No event channels are 'live' right now. */
- }
-
- /* No IRQ -> event-channel mappings. */
- for ( i = 0; i < NR_IRQS; i++ )
- irq_to_evtchn[i] = -1;
-
- for ( i = 0; i < NR_DYNIRQS; i++ )
- {
- /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- irq_bindcount[dynirq_to_irq(i)] = 0;
-
- irq_desc[dynirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[dynirq_to_irq(i)].action = 0;
- irq_desc[dynirq_to_irq(i)].depth = 1;
- irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
- }
-
- for ( i = 0; i < NR_PIRQS; i++ )
- {
- /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
- irq_bindcount[pirq_to_irq(i)] = 1;
-
- irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[pirq_to_irq(i)].action = 0;
- irq_desc[pirq_to_irq(i)].depth = 1;
- irq_desc[pirq_to_irq(i)].handler = &pirq_type;
- }
-
- (void)setup_irq(bind_virq_to_irq(VIRQ_MISDIRECT), &misdirect_action);
-
- /* This needs to be done early, but after the IRQ subsystem is alive. */
- ctrl_if_init();
-}
+++ /dev/null
-/******************************************************************************
- * xen/mm/hypervisor.c
- *
- * Update page tables via the hypervisor.
- *
- * Copyright (c) 2002, K A Fraser
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <asm/hypervisor.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/multicall.h>
-
-/*
- * This suffices to protect us if we ever move to SMP domains.
- * Further, it protects us against interrupts. At the very least, this is
- * required for the network driver which flushes the update queue before
- * pushing new receive buffers.
- */
-static spinlock_t update_lock = SPIN_LOCK_UNLOCKED;
-
-#define QUEUE_SIZE 2048
-static mmu_update_t update_queue[QUEUE_SIZE];
-unsigned int mmu_update_queue_idx = 0;
-#define idx mmu_update_queue_idx
-
-#if MMU_UPDATE_DEBUG > 0
-page_update_debug_t update_debug_queue[QUEUE_SIZE] = {{0}};
-#undef queue_l1_entry_update
-#undef queue_l2_entry_update
-static void DEBUG_allow_pt_reads(void)
-{
- pte_t *pte;
- mmu_update_t update;
- int i;
- for ( i = idx-1; i >= 0; i-- )
- {
- pte = update_debug_queue[i].ptep;
- if ( pte == NULL ) continue;
- update_debug_queue[i].ptep = NULL;
- update.ptr = virt_to_machine(pte);
- update.val = update_debug_queue[i].pteval;
- HYPERVISOR_mmu_update(&update, 1, NULL);
- }
-}
-static void DEBUG_disallow_pt_read(unsigned long va)
-{
- pte_t *pte;
- pmd_t *pmd;
- pgd_t *pgd;
- unsigned long pteval;
- /*
- * We may fault because of an already outstanding update.
- * That's okay -- it'll get fixed up in the fault handler.
- */
- mmu_update_t update;
- pgd = pgd_offset_k(va);
- pmd = pmd_offset(pgd, va);
- pte = pte_offset(pmd, va);
- update.ptr = virt_to_machine(pte);
- pteval = *(unsigned long *)pte;
- update.val = pteval & ~_PAGE_PRESENT;
- HYPERVISOR_mmu_update(&update, 1, NULL);
- update_debug_queue[idx].ptep = pte;
- update_debug_queue[idx].pteval = pteval;
-}
-#endif
-
-#if MMU_UPDATE_DEBUG > 1
-#undef queue_pt_switch
-#undef queue_tlb_flush
-#undef queue_invlpg
-#undef queue_pgd_pin
-#undef queue_pgd_unpin
-#undef queue_pte_pin
-#undef queue_pte_unpin
-#endif
-
-
-/*
- * MULTICALL_flush_page_update_queue:
- * This is a version of the flush which queues as part of a multicall.
- */
-void MULTICALL_flush_page_update_queue(void)
-{
- unsigned long flags;
- unsigned int _idx;
- spin_lock_irqsave(&update_lock, flags);
- if ( (_idx = idx) != 0 )
- {
-#if MMU_UPDATE_DEBUG > 1
- printk("Flushing %d entries from pt update queue\n", idx);
-#endif
-#if MMU_UPDATE_DEBUG > 0
- DEBUG_allow_pt_reads();
-#endif
- idx = 0;
- wmb(); /* Make sure index is cleared first to avoid double updates. */
- queue_multicall3(__HYPERVISOR_mmu_update,
- (unsigned long)update_queue,
- (unsigned long)_idx,
- (unsigned long)NULL);
- }
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-static inline void __flush_page_update_queue(void)
-{
- unsigned int _idx = idx;
-#if MMU_UPDATE_DEBUG > 1
- printk("Flushing %d entries from pt update queue\n", idx);
-#endif
-#if MMU_UPDATE_DEBUG > 0
- DEBUG_allow_pt_reads();
-#endif
- idx = 0;
- wmb(); /* Make sure index is cleared first to avoid double updates. */
- if ( unlikely(HYPERVISOR_mmu_update(update_queue, _idx, NULL) < 0) )
- {
- printk(KERN_ALERT "Failed to execute MMU updates.\n");
- BUG();
- }
-}
-
-void _flush_page_update_queue(void)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- if ( idx != 0 ) __flush_page_update_queue();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-static inline void increment_index(void)
-{
- idx++;
- if ( unlikely(idx == QUEUE_SIZE) ) __flush_page_update_queue();
-}
-
-void queue_l1_entry_update(pte_t *ptr, unsigned long val)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
-#if MMU_UPDATE_DEBUG > 0
- DEBUG_disallow_pt_read((unsigned long)ptr);
-#endif
- update_queue[idx].ptr = virt_to_machine(ptr);
- update_queue[idx].val = val;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_l2_entry_update(pmd_t *ptr, unsigned long val)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = virt_to_machine(ptr);
- update_queue[idx].val = val;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_pt_switch(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = phys_to_machine(ptr);
- update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_NEW_BASEPTR;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_tlb_flush(void)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_TLB_FLUSH;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_invlpg(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = MMU_EXTENDED_COMMAND;
- update_queue[idx].ptr |= ptr & PAGE_MASK;
- update_queue[idx].val = MMUEXT_INVLPG;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_pgd_pin(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = phys_to_machine(ptr);
- update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_PIN_L2_TABLE;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_pgd_unpin(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = phys_to_machine(ptr);
- update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_UNPIN_TABLE;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_pte_pin(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = phys_to_machine(ptr);
- update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_PIN_L1_TABLE;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_pte_unpin(unsigned long ptr)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = phys_to_machine(ptr);
- update_queue[idx].ptr |= MMU_EXTENDED_COMMAND;
- update_queue[idx].val = MMUEXT_UNPIN_TABLE;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_set_ldt(unsigned long ptr, unsigned long len)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = MMU_EXTENDED_COMMAND | ptr;
- update_queue[idx].val = MMUEXT_SET_LDT | (len << MMUEXT_CMD_SHIFT);
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-void queue_machphys_update(unsigned long mfn, unsigned long pfn)
-{
- unsigned long flags;
- spin_lock_irqsave(&update_lock, flags);
- update_queue[idx].ptr = (mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
- update_queue[idx].val = pfn;
- increment_index();
- spin_unlock_irqrestore(&update_lock, flags);
-}
-
-#ifdef CONFIG_XEN_PHYSDEV_ACCESS
-
-unsigned long allocate_empty_lowmem_region(unsigned long pages)
-{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long *pfn_array;
- unsigned long vstart;
- unsigned long i;
- int ret;
- unsigned int order = get_order(pages*PAGE_SIZE);
-
- vstart = __get_free_pages(GFP_KERNEL, order);
- if ( vstart == 0 )
- return 0UL;
-
- pfn_array = vmalloc((1<<order) * sizeof(*pfn_array));
- if ( pfn_array == NULL )
- BUG();
-
- for ( i = 0; i < (1<<order); i++ )
- {
- pgd = pgd_offset_k( (vstart + (i*PAGE_SIZE)));
- pmd = pmd_offset(pgd, (vstart + (i*PAGE_SIZE)));
- pte = pte_offset(pmd, (vstart + (i*PAGE_SIZE)));
- pfn_array[i] = pte->pte_low >> PAGE_SHIFT;
- queue_l1_entry_update(pte, 0);
- phys_to_machine_mapping[__pa(vstart)>>PAGE_SHIFT] = 0xdeadbeef;
- }
-
- flush_page_update_queue();
-
- ret = HYPERVISOR_dom_mem_op(MEMOP_decrease_reservation,
- pfn_array, 1<<order);
- if ( unlikely(ret != (1<<order)) )
- {
- printk(KERN_WARNING "Unable to reduce memory reservation (%d)\n", ret);
- BUG();
- }
-
- vfree(pfn_array);
-
- return vstart;
-}
-
-void deallocate_lowmem_region(unsigned long vstart, unsigned long pages)
-{
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte;
- unsigned long *pfn_array;
- unsigned long i;
- int ret;
- unsigned int order = get_order(pages*PAGE_SIZE);
-
- pfn_array = vmalloc((1<<order) * sizeof(*pfn_array));
- if ( pfn_array == NULL )
- BUG();
-
- ret = HYPERVISOR_dom_mem_op(MEMOP_increase_reservation,
- pfn_array, 1<<order);
- if ( unlikely(ret != (1<<order)) )
- {
- printk(KERN_WARNING "Unable to increase memory reservation (%d)\n",
- ret);
- BUG();
- }
-
- for ( i = 0; i < (1<<order); i++ )
- {
- pgd = pgd_offset_k( (vstart + (i*PAGE_SIZE)));
- pmd = pmd_offset(pgd, (vstart + (i*PAGE_SIZE)));
- pte = pte_offset(pmd, (vstart + (i*PAGE_SIZE)));
- queue_l1_entry_update(pte, (pfn_array[i]<<PAGE_SHIFT)|__PAGE_KERNEL);
- queue_machphys_update(pfn_array[i], __pa(vstart)>>PAGE_SHIFT);
- phys_to_machine_mapping[__pa(vstart)>>PAGE_SHIFT] = pfn_array[i];
- }
-
- flush_page_update_queue();
-
- vfree(pfn_array);
-
- free_pages(vstart, order);
-}
-
-#endif /* CONFIG_XEN_PHYSDEV_ACCESS */
+++ /dev/null
-/******************************************************************************
- * ctrl_if.h
- *
- * Management functions for special interface to the domain controller.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __ASM_XEN__CTRL_IF_H__
-#define __ASM_XEN__CTRL_IF_H__
-
-#include <linux/tqueue.h>
-#include <asm/hypervisor.h>
-
-typedef control_msg_t ctrl_msg_t;
-
-/*
- * Callback function type. Called for asynchronous processing of received
- * request messages, and responses to previously-transmitted request messages.
- * The parameters are (@msg, @id).
- * @msg: Original request/response message (not a copy). The message can be
- * modified in-place by the handler (e.g., a response callback can
- * turn a request message into a response message in place). The message
- * is no longer accessible after the callback handler returns -- if the
- * message is required to persist for longer then it must be copied.
- * @id: (Response callbacks only) The 'id' that was specified when the
- * original request message was queued for transmission.
- */
-typedef void (*ctrl_msg_handler_t)(ctrl_msg_t *, unsigned long);
-
-/*
- * Send @msg to the domain controller. Execute @hnd when a response is
- * received, passing the response message and the specified @id. This
- * operation will not block: it will return -EAGAIN if there is no space.
- * Notes:
- * 1. The @msg is copied if it is transmitted and so can be freed after this
- * function returns.
- * 2. If @hnd is NULL then no callback is executed.
- */
-int ctrl_if_send_message_noblock(
- ctrl_msg_t *msg,
- ctrl_msg_handler_t hnd,
- unsigned long id);
-
-/*
- * Send @msg to the domain controller. Execute @hnd when a response is
- * received, passing the response message and the specified @id. This
- * operation will block until the message is sent, or a signal is received
- * for the calling process (unless @wait_state is TASK_UNINTERRUPTIBLE).
- * Notes:
- * 1. The @msg is copied if it is transmitted and so can be freed after this
- * function returns.
- * 2. If @hnd is NULL then no callback is executed.
- */
-int ctrl_if_send_message_block(
- ctrl_msg_t *msg,
- ctrl_msg_handler_t hnd,
- unsigned long id,
- long wait_state);
-
-/*
- * Request a callback when there is /possibly/ space to immediately send a
- * message to the domain controller. This function returns 0 if there is
- * already space to trasnmit a message --- in this case the callback task /may/
- * still be executed. If this function returns 1 then the callback /will/ be
- * executed when space becomes available.
- */
-int ctrl_if_enqueue_space_callback(struct tq_struct *task);
-
-/*
- * Send a response (@msg) to a message from the domain controller. This will
- * never block.
- * Notes:
- * 1. The @msg is copied and so can be freed after this function returns.
- * 2. The @msg may be the original request message, modified in-place.
- */
-void ctrl_if_send_response(ctrl_msg_t *msg);
-
-/*
- * Register a receiver for typed messages from the domain controller. The
- * handler (@hnd) is called for every received message of specified @type.
- * Returns TRUE (non-zero) if the handler was successfully registered.
- * If CALLBACK_IN_BLOCKING CONTEXT is specified in @flags then callbacks will
- * occur in a context in which it is safe to yield (i.e., process context).
- */
-#define CALLBACK_IN_BLOCKING_CONTEXT 1
-int ctrl_if_register_receiver(
- u8 type,
- ctrl_msg_handler_t hnd,
- unsigned int flags);
-
-/*
- * Unregister a receiver for typed messages from the domain controller. The
- * handler (@hnd) will not be executed after this function returns.
- */
-void ctrl_if_unregister_receiver(u8 type, ctrl_msg_handler_t hnd);
-
-/* Suspend/resume notifications. */
-void ctrl_if_suspend(void);
-void ctrl_if_resume(void);
-
-/* Start-of-day setup. */
-void ctrl_if_init(void);
-
-/*
- * Returns TRUE if there are no outstanding message requests at the domain
- * controller. This can be used to ensure that messages have really flushed
- * through when it is not possible to use the response-callback interface.
- * WARNING: If other subsystems are using the control interface then this
- * function might never return TRUE!
- */
-int ctrl_if_transmitter_empty(void); /* !! DANGEROUS FUNCTION !! */
-
-/*
- * Manually discard response messages from the domain controller.
- * WARNING: This is usually done automatically -- this function should only
- * be called when normal interrupt mechanisms are disabled!
- */
-void ctrl_if_discard_responses(void); /* !! DANGEROUS FUNCTION !! */
-
-#endif /* __ASM_XEN__CONTROL_IF_H__ */
+++ /dev/null
-/******************************************************************************
- * evtchn.h
- *
- * Communication via Xen event channels.
- * Also definitions for the device that demuxes notifications to userspace.
- *
- * Copyright (c) 2004, K A Fraser
- */
-
-#ifndef __ASM_EVTCHN_H__
-#define __ASM_EVTCHN_H__
-
-#include <linux/config.h>
-#include <asm/hypervisor.h>
-#include <asm/ptrace.h>
-#include <asm/synch_bitops.h>
-#include <asm/hypervisor-ifs/event_channel.h>
-
-/*
- * LOW-LEVEL DEFINITIONS
- */
-
-/* Entry point for notifications into Linux subsystems. */
-void evtchn_do_upcall(struct pt_regs *regs);
-
-/* Entry point for notifications into the userland character device. */
-void evtchn_device_upcall(int port);
-
-static inline void mask_evtchn(int port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_set_bit(port, &s->evtchn_mask[0]);
-}
-
-static inline void unmask_evtchn(int port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
-
- synch_clear_bit(port, &s->evtchn_mask[0]);
-
- /*
- * The following is basically the equivalent of 'hw_resend_irq'. Just like
- * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
- */
- if ( synch_test_bit (port, &s->evtchn_pending[0]) &&
- !synch_test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
- {
- s->vcpu_data[0].evtchn_upcall_pending = 1;
- if ( !s->vcpu_data[0].evtchn_upcall_mask )
- evtchn_do_upcall(NULL);
- }
-}
-
-static inline void clear_evtchn(int port)
-{
- shared_info_t *s = HYPERVISOR_shared_info;
- synch_clear_bit(port, &s->evtchn_pending[0]);
-}
-
-static inline void notify_via_evtchn(int port)
-{
- evtchn_op_t op;
- op.cmd = EVTCHNOP_send;
- op.u.send.local_port = port;
- (void)HYPERVISOR_event_channel_op(&op);
-}
-
-/*
- * CHARACTER-DEVICE DEFINITIONS
- */
-
-/* /dev/xen/evtchn resides at device number major=10, minor=200 */
-#define EVTCHN_MINOR 200
-
-/* /dev/xen/evtchn ioctls: */
-/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
-#define EVTCHN_RESET _IO('E', 1)
-/* EVTCHN_BIND: Bind to teh specified event-channel port. */
-#define EVTCHN_BIND _IO('E', 2)
-/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
-#define EVTCHN_UNBIND _IO('E', 3)
-
-#endif /* __ASM_EVTCHN_H__ */
+++ /dev/null
-/******************************************************************************
- * hypervisor.h
- *
- * Linux-specific hypervisor handling.
- *
- * Copyright (c) 2002, K A Fraser
- */
-
-#ifndef __HYPERVISOR_H__
-#define __HYPERVISOR_H__
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/hypervisor-ifs/hypervisor-if.h>
-#include <asm/hypervisor-ifs/dom0_ops.h>
-#include <asm/hypervisor-ifs/io/domain_controller.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-
-/* arch/xen/kernel/setup.c */
-union start_info_union
-{
- extended_start_info_t start_info;
- char padding[512];
-};
-extern union start_info_union start_info_union;
-#define start_info (start_info_union.start_info)
-
-/* arch/xen/mm/hypervisor.c */
-/*
- * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
- * be MACHINE addresses.
- */
-
-extern unsigned int mmu_update_queue_idx;
-
-void queue_l1_entry_update(pte_t *ptr, unsigned long val);
-void queue_l2_entry_update(pmd_t *ptr, unsigned long val);
-void queue_pt_switch(unsigned long ptr);
-void queue_tlb_flush(void);
-void queue_invlpg(unsigned long ptr);
-void queue_pgd_pin(unsigned long ptr);
-void queue_pgd_unpin(unsigned long ptr);
-void queue_pte_pin(unsigned long ptr);
-void queue_pte_unpin(unsigned long ptr);
-void queue_set_ldt(unsigned long ptr, unsigned long bytes);
-void queue_machphys_update(unsigned long mfn, unsigned long pfn);
-#define MMU_UPDATE_DEBUG 0
-
-#if MMU_UPDATE_DEBUG > 0
-typedef struct {
- void *ptr;
- unsigned long val, pteval;
- void *ptep;
- int line; char *file;
-} page_update_debug_t;
-extern page_update_debug_t update_debug_queue[];
-#define queue_l1_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- queue_l1_entry_update((_p),(_v)); \
-})
-#define queue_l2_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- queue_l2_entry_update((_p),(_v)); \
-})
-#endif
-
-#if MMU_UPDATE_DEBUG > 1
-#undef queue_l1_entry_update
-#undef queue_l2_entry_update
-#define queue_l1_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- printk("L1 %s %d: %08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p), pte_val(_p), \
- (unsigned long)(_v)); \
- queue_l1_entry_update((_p),(_v)); \
-})
-#define queue_l2_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- printk("L2 %s %d: %08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p), pmd_val(_p), \
- (unsigned long)(_v)); \
- queue_l2_entry_update((_p),(_v)); \
-})
-#define queue_pt_switch(_p) ({ \
- printk("PTSWITCH %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pt_switch(_p); \
-})
-#define queue_tlb_flush() ({ \
- printk("TLB FLUSH %s %d\n", __FILE__, __LINE__); \
- queue_tlb_flush(); \
-})
-#define queue_invlpg(_p) ({ \
- printk("INVLPG %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_invlpg(_p); \
-})
-#define queue_pgd_pin(_p) ({ \
- printk("PGD PIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pgd_pin(_p); \
-})
-#define queue_pgd_unpin(_p) ({ \
- printk("PGD UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pgd_unpin(_p); \
-})
-#define queue_pte_pin(_p) ({ \
- printk("PTE PIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pte_pin(_p); \
-})
-#define queue_pte_unpin(_p) ({ \
- printk("PTE UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pte_unpin(_p); \
-})
-#define queue_set_ldt(_p,_l) ({ \
- printk("SETL LDT %s %d: %08lx %d\n", __FILE__, __LINE__, (_p), (_l)); \
- queue_set_ldt((_p), (_l)); \
-})
-#endif
-
-void _flush_page_update_queue(void);
-static inline int flush_page_update_queue(void)
-{
- unsigned int idx = mmu_update_queue_idx;
- if ( idx != 0 ) _flush_page_update_queue();
- return idx;
-}
-#define XEN_flush_page_update_queue() (_flush_page_update_queue())
-void MULTICALL_flush_page_update_queue(void);
-
-#ifdef CONFIG_XEN_PHYSDEV_ACCESS
-/* Allocate a contiguous empty region of low memory. Return virtual start. */
-unsigned long allocate_empty_lowmem_region(unsigned long pages);
-/* Deallocate a contiguous region of low memory. Return it to the allocator. */
-void deallocate_lowmem_region(unsigned long vstart, unsigned long pages);
-#endif
-
-/*
- * Assembler stubs for hyper-calls.
- */
-
-static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
- "b" (table) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_mmu_update(mmu_update_t *req,
- int count,
- int *success_count)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
- "b" (req), "c" (count), "d" (success_count) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_gdt),
- "b" (frame_list), "c" (entries) : "memory" );
-
-
- return ret;
-}
-
-static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_stack_switch),
- "b" (ss), "c" (esp) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_callbacks(
- unsigned long event_selector, unsigned long event_address,
- unsigned long failsafe_selector, unsigned long failsafe_address)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
- "b" (event_selector), "c" (event_address),
- "d" (failsafe_selector), "S" (failsafe_address) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_fpu_taskswitch(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_yield(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_yield) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_block(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_block) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_shutdown(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
- : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_reboot(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
- : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_suspend(unsigned long srec)
-{
- int ret;
- /* NB. On suspend, control software expects a suspend record in %esi. */
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
- "S" (srec) : "memory" );
-
- return ret;
-}
-
-static inline long HYPERVISOR_set_timer_op(u64 timeout)
-{
- int ret;
- unsigned long timeout_hi = (unsigned long)(timeout>>32);
- unsigned long timeout_lo = (unsigned long)timeout;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op),
- "b" (timeout_hi), "c" (timeout_lo) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
-{
- int ret;
- dom0_op->interface_version = DOM0_INTERFACE_VERSION;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
- "b" (dom0_op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg),
- "b" (reg), "c" (value) : "memory" );
-
- return ret;
-}
-
-static inline unsigned long HYPERVISOR_get_debugreg(int reg)
-{
- unsigned long ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg),
- "b" (reg) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_descriptor(
- unsigned long pa, unsigned long word1, unsigned long word2)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor),
- "b" (pa), "c" (word1), "d" (word2) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_fast_trap(int idx)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap),
- "b" (idx) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_dom_mem_op(unsigned int op,
- unsigned long *pages,
- unsigned long nr_pages)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
- "b" (op), "c" (pages), "d" (nr_pages) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_multicall),
- "b" (call_list), "c" (nr_calls) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_va_mapping(
- unsigned long page_nr, pte_t new_val, unsigned long flags)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping),
- "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) : "memory" );
-
- if ( unlikely(ret < 0) )
- {
- printk(KERN_ALERT "Failed update VA mapping: %08lx, %08lx, %08lx\n",
- page_nr, (new_val).pte_low, flags);
- BUG();
- }
-
- return ret;
-}
-
-static inline int HYPERVISOR_event_channel_op(void *op)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_event_channel_op),
- "b" (op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_xen_version(int cmd)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_xen_version),
- "b" (cmd) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_console_io),
- "b" (cmd), "c" (count), "d" (str) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_physdev_op(void *physdev_op)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_physdev_op),
- "b" (physdev_op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_va_mapping_otherdomain(
- unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
- "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) :
- "memory" );
-
- return ret;
-}
-
-#endif /* __HYPERVISOR_H__ */
+++ /dev/null
-/******************************************************************************
- * multicall.h
- */
-
-#ifndef __MULTICALL_H__
-#define __MULTICALL_H__
-
-#include <asm/hypervisor.h>
-
-extern multicall_entry_t multicall_list[];
-extern int nr_multicall_ents;
-
-static inline void queue_multicall0(unsigned long op)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- nr_multicall_ents = i+1;
-}
-
-static inline void queue_multicall1(unsigned long op, unsigned long arg1)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- multicall_list[i].args[0] = arg1;
- nr_multicall_ents = i+1;
-}
-
-static inline void queue_multicall2(
- unsigned long op, unsigned long arg1, unsigned long arg2)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- multicall_list[i].args[0] = arg1;
- multicall_list[i].args[1] = arg2;
- nr_multicall_ents = i+1;
-}
-
-static inline void queue_multicall3(
- unsigned long op, unsigned long arg1, unsigned long arg2,
- unsigned long arg3)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- multicall_list[i].args[0] = arg1;
- multicall_list[i].args[1] = arg2;
- multicall_list[i].args[2] = arg3;
- nr_multicall_ents = i+1;
-}
-
-static inline void queue_multicall4(
- unsigned long op, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- multicall_list[i].args[0] = arg1;
- multicall_list[i].args[1] = arg2;
- multicall_list[i].args[2] = arg3;
- multicall_list[i].args[3] = arg4;
- nr_multicall_ents = i+1;
-}
-
-static inline void queue_multicall5(
- unsigned long op, unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4, unsigned long arg5)
-{
- int i = nr_multicall_ents;
- multicall_list[i].op = op;
- multicall_list[i].args[0] = arg1;
- multicall_list[i].args[1] = arg2;
- multicall_list[i].args[2] = arg3;
- multicall_list[i].args[3] = arg4;
- multicall_list[i].args[4] = arg5;
- nr_multicall_ents = i+1;
-}
-
-static inline void execute_multicall_list(void)
-{
- if ( unlikely(nr_multicall_ents == 0) ) return;
- (void)HYPERVISOR_multicall(multicall_list, nr_multicall_ents);
- nr_multicall_ents = 0;
-}
-
-#endif /* __MULTICALL_H__ */
+++ /dev/null
-/******************************************************************************
- * proc_cmd.h
- *
- * Interface to /proc/cmd and /proc/xen/privcmd.
- */
-
-#ifndef __PROC_CMD_H__
-#define __PROC_CMD_H__
-
-typedef struct privcmd_hypercall
-{
- unsigned long op;
- unsigned long arg[5];
-} privcmd_hypercall_t;
-
-typedef struct privcmd_mmap_entry {
- unsigned long va;
- unsigned long mfn;
- unsigned long npages;
-} privcmd_mmap_entry_t;
-
-typedef struct privcmd_mmap {
- int num;
- domid_t dom; /* target domain */
- privcmd_mmap_entry_t *entry;
-} privcmd_mmap_t;
-
-typedef struct privcmd_mmapbatch {
- int num; // number of pages to populate
- domid_t dom; // target domain
- unsigned long addr; // virtual address
- unsigned long *arr; // array of mfns - top nibble set on err
-} privcmd_mmapbatch_t;
-
-typedef struct privcmd_blkmsg
-{
- unsigned long op;
- void *buf;
- int buf_size;
-} privcmd_blkmsg_t;
-
-/*
- * @cmd: IOCTL_PRIVCMD_HYPERCALL
- * @arg: &privcmd_hypercall_t
- * Return: Value returned from execution of the specified hypercall.
- */
-#define IOCTL_PRIVCMD_HYPERCALL \
- _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
-
-/*
- * @cmd: IOCTL_PRIVCMD_INITDOMAIN_EVTCHN
- * @arg: n/a
- * Return: Port associated with domain-controller end of control event channel
- * for the initial domain.
- */
-#define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN \
- _IOC(_IOC_NONE, 'P', 1, 0)
-#define IOCTL_PRIVCMD_MMAP \
- _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
-#define IOCTL_PRIVCMD_MMAPBATCH \
- _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmapbatch_t))
-
-#endif /* __PROC_CMD_H__ */
+++ /dev/null
-/******************************************************************************
- * suspend.h
- *
- * NB. This file is part of the Xenolinux interface with Xenoserver control
- * software. It can be included in such software without invoking the GPL.
- *
- * Copyright (c) 2003, K A Fraser
- */
-
-#ifndef __ASM_XEN_SUSPEND_H__
-#define __ASM_XEN_SUSPEND_H__
-
-typedef struct suspend_record_st {
- /* To be filled in before resume. */
- extended_start_info_t resume_info;
- /*
- * The number of a machine frame containing, in sequence, the number of
- * each machine frame that contains PFN -> MFN translation table data.
- */
- unsigned long pfn_to_mfn_frame_list;
- /* Number of entries in the PFN -> MFN translation table. */
- unsigned long nr_pfns;
-} suspend_record_t;
-
-#endif /* __ASM_XEN_SUSPEND_H__ */
ln -sf ../asm-i386/unaligned.h
ln -sf ../asm-i386/unistd.h
ln -sf ../asm-i386/user.h
+ln -sf ../../${LINUX_26}/include/asm-xen/ctrl_if.h
+ln -sf ../../${LINUX_26}/include/asm-xen/evtchn.h
+ln -sf ../../${LINUX_26}/include/asm-xen/hypervisor.h
+ln -sf ../../${LINUX_26}/include/asm-xen/multicall.h
+ln -sf ../../${LINUX_26}/include/asm-xen/proc_cmd.h
+ln -sf ../../${LINUX_26}/include/asm-xen/suspend.h
ln -sf ../../${LINUX_26}/include/asm-xen/xen_proc.h
cd ${AD}/arch/xen/kernel
ln -sf ../../i386/kernel/ptrace.c
ln -sf ../../i386/kernel/semaphore.c
ln -sf ../../i386/kernel/sys_i386.c
+ln -sf ../../../${LINUX_26}/arch/xen/kernel/ctrl_if.c
+ln -sf ../../../${LINUX_26}/arch/xen/kernel/evtchn.c
ln -sf ../../../${LINUX_26}/arch/xen/i386/kernel/ioport.c
cd ${AD}/arch/xen/lib
cd ${AD}/arch/xen/mm
ln -sf ../../i386/mm/extable.c
ln -sf ../../i386/mm/pageattr.c
+ln -sf ../../../${LINUX_26}/arch/xen/i386/mm/hypervisor.c
cd ${AD}/arch/xen/drivers/console
ln -sf ../../../../${LINUX_26}/drivers/xen/console/console.c
cd ${AD}/arch/xen/drivers/dom0
ln -sf ../../../../${LINUX_26}/drivers/xen/privcmd/privcmd.c core.c
+cd ${AD}/arch/xen/drivers/evtchn
+ln -sf ../../../../${LINUX_26}/drivers/xen/evtchn/evtchn.c
+
cd ${AD}/arch/xen/drivers/netif/frontend
ln -sf ../../../../../${LINUX_26}/drivers/xen/netfront/netfront.c main.c
doublefault.o
s-obj-y :=
-#obj-y += hypervisor.o
-obj-y += evtchn.o
-
obj-y += cpu/
obj-y += timers/
c-obj-$(CONFIG_ACPI_BOOT) += acpi/
#include <asm/msr.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
#include "cpu.h"
+++ /dev/null
-/******************************************************************************
- * evtchn.c
- *
- * Communication via Xen event channels.
- *
- * Copyright (c) 2002-2004, K A Fraser
- */
-
-#include <linux/config.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <asm/atomic.h>
-#include <asm/system.h>
-#include <asm/ptrace.h>
-#include <asm/synch_bitops.h>
-#include <asm/hypervisor.h>
-#include <asm/hypervisor-ifs/event_channel.h>
-#include <asm/hypervisor-ifs/physdev.h>
-#include <asm-xen/ctrl_if.h>
-
-/*
- * This lock protects updates to the following mapping and reference-count
- * arrays. The lock does not need to be acquired to read the mapping tables.
- */
-static spinlock_t irq_mapping_update_lock;
-
-/* IRQ <-> event-channel mappings. */
-static int evtchn_to_irq[NR_EVENT_CHANNELS];
-static int irq_to_evtchn[NR_IRQS];
-
-/* IRQ <-> VIRQ mapping. */
-static int virq_to_irq[NR_VIRQS];
-
-/* Reference counts for bindings to IRQs. */
-static int irq_bindcount[NR_IRQS];
-
-/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
-static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
-
-/* Upcall to generic IRQ layer. */
-extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
-
-#define VALID_EVTCHN(_chn) ((_chn) != -1)
-
-void evtchn_do_upcall(struct pt_regs *regs)
-{
- unsigned long l1, l2;
- unsigned int l1i, l2i, port;
- int irq;
- unsigned long flags;
- shared_info_t *s = HYPERVISOR_shared_info;
-
- local_irq_save(flags);
-
- while ( s->vcpu_data[0].evtchn_upcall_pending )
- {
- s->vcpu_data[0].evtchn_upcall_pending = 0;
- /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
- l1 = xchg(&s->evtchn_pending_sel, 0);
- while ( (l1i = ffs(l1)) != 0 )
- {
- l1i--;
- l1 &= ~(1 << l1i);
-
- l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
- while ( (l2i = ffs(l2)) != 0 )
- {
- l2i--;
- l2 &= ~(1 << l2i);
-
- port = (l1i << 5) + l2i;
- if ( (irq = evtchn_to_irq[port]) != -1 )
- do_IRQ(irq, regs);
- else
- evtchn_device_upcall(port);
- }
- }
- }
-
- local_irq_restore(flags);
-}
-
-
-static int find_unbound_irq(void)
-{
- int irq;
-
- for ( irq = 0; irq < NR_IRQS; irq++ )
- if ( irq_bindcount[irq] == 0 )
- break;
-
- if ( irq == NR_IRQS )
- panic("No available IRQ to bind to: increase NR_IRQS!\n");
-
- return irq;
-}
-
-int bind_virq_to_irq(int virq)
-{
- evtchn_op_t op;
- int evtchn, irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = virq_to_irq[virq]) == -1 )
- {
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to bind virtual IRQ %d\n", virq);
- evtchn = op.u.bind_virq.port;
-
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- virq_to_irq[virq] = irq;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
-}
-
-void unbind_virq_from_irq(int virq)
-{
- evtchn_op_t op;
- int irq = virq_to_irq[virq];
- int evtchn = irq_to_evtchn[irq];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- op.cmd = EVTCHNOP_close;
- op.u.close.dom = DOMID_SELF;
- op.u.close.port = evtchn;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to unbind virtual IRQ %d\n", virq);
-
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- virq_to_irq[virq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-
-int bind_evtchn_to_irq(int evtchn)
-{
- int irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( (irq = evtchn_to_irq[evtchn]) == -1 )
- {
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
-}
-
-void unbind_evtchn_from_irq(int evtchn)
-{
- int irq = evtchn_to_irq[evtchn];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ( --irq_bindcount[irq] == 0 )
- {
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-
-
-/*
- * Interface to generic handling in irq.c
- */
-
-static unsigned int startup_dynirq(unsigned int irq)
-{
- unmask_evtchn(irq_to_evtchn[irq]);
- return 0;
-}
-
-static void shutdown_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void enable_dynirq(unsigned int irq)
-{
- unmask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void disable_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
-}
-
-static void ack_dynirq(unsigned int irq)
-{
- mask_evtchn(irq_to_evtchn[irq]);
- clear_evtchn(irq_to_evtchn[irq]);
-}
-
-static void end_dynirq(unsigned int irq)
-{
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- unmask_evtchn(irq_to_evtchn[irq]);
-}
-
-static struct hw_interrupt_type dynirq_type = {
- "Dynamic-irq",
- startup_dynirq,
- shutdown_dynirq,
- enable_dynirq,
- disable_dynirq,
- ack_dynirq,
- end_dynirq,
- NULL
-};
-
-static inline void pirq_unmask_notify(int pirq)
-{
- physdev_op_t op;
- if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
- {
- op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
- (void)HYPERVISOR_physdev_op(&op);
- }
-}
-
-static inline void pirq_query_unmask(int pirq)
-{
- physdev_op_t op;
- op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
- op.u.irq_status_query.irq = pirq;
- (void)HYPERVISOR_physdev_op(&op);
- clear_bit(pirq, &pirq_needs_unmask_notify[0]);
- if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
- set_bit(pirq, &pirq_needs_unmask_notify[0]);
-}
-
-/*
- * On startup, if there is no action associated with the IRQ then we are
- * probing. In this case we should not share with others as it will confuse us.
- */
-#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
-
-static unsigned int startup_pirq(unsigned int irq)
-{
- evtchn_op_t op;
- int evtchn;
-
- op.cmd = EVTCHNOP_bind_pirq;
- op.u.bind_pirq.pirq = irq;
- /* NB. We are happy to share unless we are probing. */
- op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- {
- if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
- printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
- return 0;
- }
- evtchn = op.u.bind_pirq.port;
-
- pirq_query_unmask(irq_to_pirq(irq));
-
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
-
- return 0;
-}
-
-static void shutdown_pirq(unsigned int irq)
-{
- evtchn_op_t op;
- int evtchn = irq_to_evtchn[irq];
-
- if ( !VALID_EVTCHN(evtchn) )
- return;
-
- mask_evtchn(evtchn);
-
- op.cmd = EVTCHNOP_close;
- op.u.close.dom = DOMID_SELF;
- op.u.close.port = evtchn;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to unbind physical IRQ %d\n", irq);
-
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
-}
-
-static void enable_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
-}
-
-static void disable_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
-}
-
-static void ack_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- mask_evtchn(evtchn);
- clear_evtchn(evtchn);
-}
-
-static void end_pirq(unsigned int irq)
-{
- int evtchn = irq_to_evtchn[irq];
- if ( !VALID_EVTCHN(evtchn) )
- return;
- if ( !(irq_desc[irq].status & IRQ_DISABLED) )
- {
- unmask_evtchn(evtchn);
- pirq_unmask_notify(irq_to_pirq(irq));
- }
-}
-
-static struct hw_interrupt_type pirq_type = {
- "Phys-irq",
- startup_pirq,
- shutdown_pirq,
- enable_pirq,
- disable_pirq,
- ack_pirq,
- end_pirq,
- NULL
-};
-
-static irqreturn_t misdirect_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
-{
- /* nothing */
- return IRQ_HANDLED;
-}
-
-static struct irqaction misdirect_action = {
- misdirect_interrupt,
- SA_INTERRUPT,
- 0,
- "misdirect",
- NULL,
- NULL
-};
-
-void irq_suspend(void)
-{
- int virq, irq, evtchn;
-
- /* Unbind VIRQs from event channels. */
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- {
- if ( (irq = virq_to_irq[virq]) == -1 )
- continue;
- evtchn = irq_to_evtchn[irq];
-
- /* Mark the event channel as unused in our table. */
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- }
-
- /*
- * We should now be unbound from all event channels. Stale bindings to
- * PIRQs and/or inter-domain event channels will cause us to barf here.
- */
- for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
- if ( evtchn_to_irq[evtchn] != -1 )
- panic("Suspend attempted while bound to evtchn %d.\n", evtchn);
-}
-
-
-void irq_resume(void)
-{
- evtchn_op_t op;
- int virq, irq, evtchn;
-
- for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
- mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
-
- for ( virq = 0; virq < NR_VIRQS; virq++ )
- {
- if ( (irq = virq_to_irq[virq]) == -1 )
- continue;
-
- /* Get a new binding from Xen. */
- op.cmd = EVTCHNOP_bind_virq;
- op.u.bind_virq.virq = virq;
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- panic("Failed to bind virtual IRQ %d\n", virq);
- evtchn = op.u.bind_virq.port;
-
- /* Record the new mapping. */
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- /* Ready for use. */
- unmask_evtchn(evtchn);
- }
-}
-
-void __init init_IRQ(void)
-{
- int i;
-
- spin_lock_init(&irq_mapping_update_lock);
-
- /* No VIRQ -> IRQ mappings. */
- for ( i = 0; i < NR_VIRQS; i++ )
- virq_to_irq[i] = -1;
-
- /* No event-channel -> IRQ mappings. */
- for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
- {
- evtchn_to_irq[i] = -1;
- mask_evtchn(i); /* No event channels are 'live' right now. */
- }
-
- /* No IRQ -> event-channel mappings. */
- for ( i = 0; i < NR_IRQS; i++ )
- irq_to_evtchn[i] = -1;
-
- for ( i = 0; i < NR_DYNIRQS; i++ )
- {
- /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- irq_bindcount[dynirq_to_irq(i)] = 0;
-
- irq_desc[dynirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[dynirq_to_irq(i)].action = 0;
- irq_desc[dynirq_to_irq(i)].depth = 1;
- irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
- }
-
- for ( i = 0; i < NR_PIRQS; i++ )
- {
- /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
- irq_bindcount[pirq_to_irq(i)] = 1;
-
- irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
- irq_desc[pirq_to_irq(i)].action = 0;
- irq_desc[pirq_to_irq(i)].depth = 1;
- irq_desc[pirq_to_irq(i)].handler = &pirq_type;
- }
-
- (void)setup_irq(bind_virq_to_irq(VIRQ_MISDIRECT), &misdirect_action);
-
- /* This needs to be done early, but after the IRQ subsystem is alive. */
- ctrl_if_init();
-}
#include <asm/io_apic.h>
#include <asm/ist.h>
#include <asm/std_resources.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
#include "setup_arch_pre.h"
int disable_pse __initdata = 0;
/******************************************************************************
- * xen/i386/mm/hypervisor.c
+ * mm/hypervisor.c
*
* Update page tables via the hypervisor.
*
- * Copyright (c) 2002, K A Fraser
+ * Copyright (c) 2002-2004, K A Fraser
*/
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
-#include <asm/hypervisor.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm-xen/hypervisor.h>
#include <asm-xen/multicall.h>
/*
*/
static spinlock_t update_lock = SPIN_LOCK_UNLOCKED;
-#if 0
+/* Linux 2.6 isn't using the traditional batched interface. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define QUEUE_SIZE 2048
+#define pte_offset_kernel pte_offset
#else
#define QUEUE_SIZE 1
#endif
+
static mmu_update_t update_queue[QUEUE_SIZE];
unsigned int mmu_update_queue_idx = 0;
#define idx mmu_update_queue_idx
#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long highstart_pfn, highend_pfn;
extra-y += vmlinux.lds.s
-obj-y := ctrl_if.o process.o reboot.o xen_proc.o empty.o
+obj-y := ctrl_if.o evtchn.o process.o reboot.o xen_proc.o empty.o
static unsigned long ctrl_if_rxmsg_blocking_context[256/sizeof(unsigned long)];
/* Is it late enough during bootstrap to use schedule_task()? */
static int safe_to_schedule_task;
-#if 0 /* XXXcl tq */
- /* Passed to schedule_task(). */
-static struct tq_struct ctrl_if_rxmsg_deferred_tq;
-#else
-static struct work_struct ctrl_if_rxmsg_deferred_work;
-#endif
/* Queue up messages to be handled in process context. */
static ctrl_msg_t ctrl_if_rxmsg_deferred[CONTROL_RING_SIZE];
static CONTROL_RING_IDX ctrl_if_rxmsg_deferred_prod;
unsigned long id;
} ctrl_if_txmsg_id_mapping[CONTROL_RING_SIZE];
-#if 0 /* XXXcl tq */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+static struct tq_struct ctrl_if_rxmsg_deferred_tq;
static DECLARE_TASK_QUEUE(ctrl_if_tx_tq);
#else
+static struct work_struct ctrl_if_rxmsg_deferred_work;
static struct workqueue_struct *ctrl_if_tx_wq = NULL;
#endif
+
static DECLARE_WAIT_QUEUE_HEAD(ctrl_if_tx_wait);
static void __ctrl_if_tx_tasklet(unsigned long data);
static DECLARE_TASKLET(ctrl_if_tx_tasklet, __ctrl_if_tx_tasklet, 0);
if ( was_full && !TX_FULL(ctrl_if) )
{
- wake_up(&ctrl_if_tx_wait);
-#if 0 /* XXXcl tq */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
run_task_queue(&ctrl_if_tx_tq);
+#else
+ wake_up(&ctrl_if_tx_wait);
#endif
}
}
if ( msg.length != 0 )
memcpy(msg.msg, pmsg->msg, msg.length);
- if ( test_bit(msg.type, (unsigned long *)&ctrl_if_rxmsg_blocking_context) )
+ if ( test_bit(msg.type,
+ (unsigned long *)&ctrl_if_rxmsg_blocking_context) )
{
pmsg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(
ctrl_if_rxmsg_deferred_prod++)];
memcpy(pmsg, &msg, offsetof(ctrl_msg_t, msg) + msg.length);
-#if 0 /* XXXcl tq */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
schedule_task(&ctrl_if_rxmsg_deferred_tq);
#else
schedule_work(&ctrl_if_rxmsg_deferred_work);
}
}
-static irqreturn_t ctrl_if_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t ctrl_if_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
{
control_if_t *ctrl_if = get_ctrl_if();
if ( !TX_FULL(ctrl_if) )
return 0;
-#if 0 /* XXXcl tq */
- (void)queue_task(task, &ctrl_if_tx_tq);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+ (void)queue_task(work, &ctrl_if_tx_tq);
#else
- if (ctrl_if_tx_wq)
+ if ( ctrl_if_tx_wq )
(void)queue_work(ctrl_if_tx_wq, work);
else
return 1;
for ( i = 0; i < 256; i++ )
ctrl_if_rxmsg_handler[i] = ctrl_if_rxmsg_default_handler;
-#if 0 /* XXXcl tq */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
ctrl_if_rxmsg_deferred_tq.routine = __ctrl_if_rxmsg_deferred;
#else
- INIT_WORK(&ctrl_if_rxmsg_deferred_work, (void *)__ctrl_if_rxmsg_deferred,
+ INIT_WORK(&ctrl_if_rxmsg_deferred_work,
+ (void *)__ctrl_if_rxmsg_deferred,
NULL);
#endif
static int __init ctrl_if_late_setup(void)
{
safe_to_schedule_task = 1;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
ctrl_if_tx_wq = create_workqueue("ctrl_if_tx");
if (ctrl_if_tx_wq == NULL)
return 1; /* XXX */
+#endif
return 0;
}
__initcall(ctrl_if_late_setup);
#include <linux/string.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
#if 0
static __inline__ int HYPERVISOR_console_write(const char *str, int count)
--- /dev/null
+/******************************************************************************
+ * evtchn.c
+ *
+ * Communication via Xen event channels.
+ *
+ * Copyright (c) 2002-2004, K A Fraser
+ */
+
+#include <linux/config.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/synch_bitops.h>
+#include <asm/hypervisor-ifs/event_channel.h>
+#include <asm/hypervisor-ifs/physdev.h>
+#include <asm-xen/ctrl_if.h>
+#include <asm-xen/hypervisor.h>
+
+/*
+ * This lock protects updates to the following mapping and reference-count
+ * arrays. The lock does not need to be acquired to read the mapping tables.
+ */
+static spinlock_t irq_mapping_update_lock;
+
+/* IRQ <-> event-channel mappings. */
+static int evtchn_to_irq[NR_EVENT_CHANNELS];
+static int irq_to_evtchn[NR_IRQS];
+
+/* IRQ <-> VIRQ mapping. */
+static int virq_to_irq[NR_VIRQS];
+
+/* Reference counts for bindings to IRQs. */
+static int irq_bindcount[NR_IRQS];
+
+/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
+static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)];
+
+/* Upcall to generic IRQ layer. */
+extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
+
+#define VALID_EVTCHN(_chn) ((_chn) != -1)
+
+void evtchn_do_upcall(struct pt_regs *regs)
+{
+ unsigned long l1, l2;
+ unsigned int l1i, l2i, port;
+ int irq;
+ unsigned long flags;
+ shared_info_t *s = HYPERVISOR_shared_info;
+
+ local_irq_save(flags);
+
+ while ( s->vcpu_data[0].evtchn_upcall_pending )
+ {
+ s->vcpu_data[0].evtchn_upcall_pending = 0;
+ /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+ l1 = xchg(&s->evtchn_pending_sel, 0);
+ while ( (l1i = ffs(l1)) != 0 )
+ {
+ l1i--;
+ l1 &= ~(1 << l1i);
+
+ l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
+ while ( (l2i = ffs(l2)) != 0 )
+ {
+ l2i--;
+ l2 &= ~(1 << l2i);
+
+ port = (l1i << 5) + l2i;
+ if ( (irq = evtchn_to_irq[port]) != -1 )
+ do_IRQ(irq, regs);
+ else
+ evtchn_device_upcall(port);
+ }
+ }
+ }
+
+ local_irq_restore(flags);
+}
+
+
+static int find_unbound_irq(void)
+{
+ int irq;
+
+ for ( irq = 0; irq < NR_IRQS; irq++ )
+ if ( irq_bindcount[irq] == 0 )
+ break;
+
+ if ( irq == NR_IRQS )
+ panic("No available IRQ to bind to: increase NR_IRQS!\n");
+
+ return irq;
+}
+
+int bind_virq_to_irq(int virq)
+{
+ evtchn_op_t op;
+ int evtchn, irq;
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ( (irq = virq_to_irq[virq]) == -1 )
+ {
+ op.cmd = EVTCHNOP_bind_virq;
+ op.u.bind_virq.virq = virq;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to bind virtual IRQ %d\n", virq);
+ evtchn = op.u.bind_virq.port;
+
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ virq_to_irq[virq] = irq;
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
+
+ return irq;
+}
+
+void unbind_virq_from_irq(int virq)
+{
+ evtchn_op_t op;
+ int irq = virq_to_irq[virq];
+ int evtchn = irq_to_evtchn[irq];
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ( --irq_bindcount[irq] == 0 )
+ {
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to unbind virtual IRQ %d\n", virq);
+
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ virq_to_irq[virq] = -1;
+ }
+
+ spin_unlock(&irq_mapping_update_lock);
+}
+
+int bind_evtchn_to_irq(int evtchn)
+{
+ int irq;
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ( (irq = evtchn_to_irq[evtchn]) == -1 )
+ {
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
+
+ return irq;
+}
+
+void unbind_evtchn_from_irq(int evtchn)
+{
+ int irq = evtchn_to_irq[evtchn];
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ( --irq_bindcount[irq] == 0 )
+ {
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ }
+
+ spin_unlock(&irq_mapping_update_lock);
+}
+
+
+/*
+ * Interface to generic handling in irq.c
+ */
+
+static unsigned int startup_dynirq(unsigned int irq)
+{
+ unmask_evtchn(irq_to_evtchn[irq]);
+ return 0;
+}
+
+static void shutdown_dynirq(unsigned int irq)
+{
+ mask_evtchn(irq_to_evtchn[irq]);
+}
+
+static void enable_dynirq(unsigned int irq)
+{
+ unmask_evtchn(irq_to_evtchn[irq]);
+}
+
+static void disable_dynirq(unsigned int irq)
+{
+ mask_evtchn(irq_to_evtchn[irq]);
+}
+
+static void ack_dynirq(unsigned int irq)
+{
+ mask_evtchn(irq_to_evtchn[irq]);
+ clear_evtchn(irq_to_evtchn[irq]);
+}
+
+static void end_dynirq(unsigned int irq)
+{
+ if ( !(irq_desc[irq].status & IRQ_DISABLED) )
+ unmask_evtchn(irq_to_evtchn[irq]);
+}
+
+static struct hw_interrupt_type dynirq_type = {
+ "Dynamic-irq",
+ startup_dynirq,
+ shutdown_dynirq,
+ enable_dynirq,
+ disable_dynirq,
+ ack_dynirq,
+ end_dynirq,
+ NULL
+};
+
+static inline void pirq_unmask_notify(int pirq)
+{
+ physdev_op_t op;
+ if ( unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0])) )
+ {
+ op.cmd = PHYSDEVOP_IRQ_UNMASK_NOTIFY;
+ (void)HYPERVISOR_physdev_op(&op);
+ }
+}
+
+static inline void pirq_query_unmask(int pirq)
+{
+ physdev_op_t op;
+ op.cmd = PHYSDEVOP_IRQ_STATUS_QUERY;
+ op.u.irq_status_query.irq = pirq;
+ (void)HYPERVISOR_physdev_op(&op);
+ clear_bit(pirq, &pirq_needs_unmask_notify[0]);
+ if ( op.u.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
+ set_bit(pirq, &pirq_needs_unmask_notify[0]);
+}
+
+/*
+ * On startup, if there is no action associated with the IRQ then we are
+ * probing. In this case we should not share with others as it will confuse us.
+ */
+#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
+
+static unsigned int startup_pirq(unsigned int irq)
+{
+ evtchn_op_t op;
+ int evtchn;
+
+ op.cmd = EVTCHNOP_bind_pirq;
+ op.u.bind_pirq.pirq = irq;
+ /* NB. We are happy to share unless we are probing. */
+ op.u.bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ {
+ if ( !probing_irq(irq) ) /* Some failures are expected when probing. */
+ printk(KERN_INFO "Failed to obtain physical IRQ %d\n", irq);
+ return 0;
+ }
+ evtchn = op.u.bind_pirq.port;
+
+ pirq_query_unmask(irq_to_pirq(irq));
+
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+
+ return 0;
+}
+
+static void shutdown_pirq(unsigned int irq)
+{
+ evtchn_op_t op;
+ int evtchn = irq_to_evtchn[irq];
+
+ if ( !VALID_EVTCHN(evtchn) )
+ return;
+
+ mask_evtchn(evtchn);
+
+ op.cmd = EVTCHNOP_close;
+ op.u.close.dom = DOMID_SELF;
+ op.u.close.port = evtchn;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to unbind physical IRQ %d\n", irq);
+
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+}
+
+static void enable_pirq(unsigned int irq)
+{
+ int evtchn = irq_to_evtchn[irq];
+ if ( !VALID_EVTCHN(evtchn) )
+ return;
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+}
+
+static void disable_pirq(unsigned int irq)
+{
+ int evtchn = irq_to_evtchn[irq];
+ if ( !VALID_EVTCHN(evtchn) )
+ return;
+ mask_evtchn(evtchn);
+}
+
+static void ack_pirq(unsigned int irq)
+{
+ int evtchn = irq_to_evtchn[irq];
+ if ( !VALID_EVTCHN(evtchn) )
+ return;
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+}
+
+static void end_pirq(unsigned int irq)
+{
+ int evtchn = irq_to_evtchn[irq];
+ if ( !VALID_EVTCHN(evtchn) )
+ return;
+ if ( !(irq_desc[irq].status & IRQ_DISABLED) )
+ {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq_to_pirq(irq));
+ }
+}
+
+static struct hw_interrupt_type pirq_type = {
+ "Phys-irq",
+ startup_pirq,
+ shutdown_pirq,
+ enable_pirq,
+ disable_pirq,
+ ack_pirq,
+ end_pirq,
+ NULL
+};
+
+static irqreturn_t misdirect_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ /* nothing */
+ return IRQ_HANDLED;
+}
+
+static struct irqaction misdirect_action = {
+ misdirect_interrupt,
+ SA_INTERRUPT,
+ 0,
+ "misdirect",
+ NULL,
+ NULL
+};
+
+void irq_suspend(void)
+{
+ int virq, irq, evtchn;
+
+ /* Unbind VIRQs from event channels. */
+ for ( virq = 0; virq < NR_VIRQS; virq++ )
+ {
+ if ( (irq = virq_to_irq[virq]) == -1 )
+ continue;
+ evtchn = irq_to_evtchn[irq];
+
+ /* Mark the event channel as unused in our table. */
+ evtchn_to_irq[evtchn] = -1;
+ irq_to_evtchn[irq] = -1;
+ }
+
+ /*
+ * We should now be unbound from all event channels. Stale bindings to
+ * PIRQs and/or inter-domain event channels will cause us to barf here.
+ */
+ for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
+ if ( evtchn_to_irq[evtchn] != -1 )
+ panic("Suspend attempted while bound to evtchn %d.\n", evtchn);
+}
+
+
+void irq_resume(void)
+{
+ evtchn_op_t op;
+ int virq, irq, evtchn;
+
+ for ( evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++ )
+ mask_evtchn(evtchn); /* New event-channel space is not 'live' yet. */
+
+ for ( virq = 0; virq < NR_VIRQS; virq++ )
+ {
+ if ( (irq = virq_to_irq[virq]) == -1 )
+ continue;
+
+ /* Get a new binding from Xen. */
+ op.cmd = EVTCHNOP_bind_virq;
+ op.u.bind_virq.virq = virq;
+ if ( HYPERVISOR_event_channel_op(&op) != 0 )
+ panic("Failed to bind virtual IRQ %d\n", virq);
+ evtchn = op.u.bind_virq.port;
+
+ /* Record the new mapping. */
+ evtchn_to_irq[evtchn] = irq;
+ irq_to_evtchn[irq] = evtchn;
+
+ /* Ready for use. */
+ unmask_evtchn(evtchn);
+ }
+}
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ spin_lock_init(&irq_mapping_update_lock);
+
+ /* No VIRQ -> IRQ mappings. */
+ for ( i = 0; i < NR_VIRQS; i++ )
+ virq_to_irq[i] = -1;
+
+ /* No event-channel -> IRQ mappings. */
+ for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
+ {
+ evtchn_to_irq[i] = -1;
+ mask_evtchn(i); /* No event channels are 'live' right now. */
+ }
+
+ /* No IRQ -> event-channel mappings. */
+ for ( i = 0; i < NR_IRQS; i++ )
+ irq_to_evtchn[i] = -1;
+
+ for ( i = 0; i < NR_DYNIRQS; i++ )
+ {
+ /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
+ irq_bindcount[dynirq_to_irq(i)] = 0;
+
+ irq_desc[dynirq_to_irq(i)].status = IRQ_DISABLED;
+ irq_desc[dynirq_to_irq(i)].action = 0;
+ irq_desc[dynirq_to_irq(i)].depth = 1;
+ irq_desc[dynirq_to_irq(i)].handler = &dynirq_type;
+ }
+
+ for ( i = 0; i < NR_PIRQS; i++ )
+ {
+ /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
+ irq_bindcount[pirq_to_irq(i)] = 1;
+
+ irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED;
+ irq_desc[pirq_to_irq(i)].action = 0;
+ irq_desc[pirq_to_irq(i)].depth = 1;
+ irq_desc[pirq_to_irq(i)].handler = &pirq_type;
+ }
+
+ (void)setup_irq(bind_virq_to_irq(VIRQ_MISDIRECT), &misdirect_action);
+
+ /* This needs to be done early, but after the IRQ subsystem is alive. */
+ ctrl_if_init();
+}
#include <linux/module.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
int reboot_thru_bios = 0; /* for dmi_scan.c */
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
-#include <asm-xen/ctrl_if.h>
#include <asm/io.h>
#include <asm/setup.h>
#include <asm/pgalloc.h>
+#include <asm-xen/ctrl_if.h>
+#include <asm-xen/hypervisor.h>
#include <asm-xen/hypervisor-ifs/io/blkif.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define irqreturn_t void
-#define IRQ_HANDLED
-#endif
-
#if 0
#define ASSERT(_p) \
if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
-#include <asm/hypervisor.h>
#include <asm/hypervisor-ifs/event_channel.h>
+#include <asm-xen/hypervisor.h>
#include <asm-xen/evtchn.h>
#include <asm-xen/ctrl_if.h>
static struct tq_struct xencons_tx_flush_task = {
routine: xencons_tx_flush_task_routine
};
-#define irqreturn_t void
-#define IRQ_HANDLED
#endif
#include <linux/poll.h>
#include <linux/irq.h>
#include <linux/init.h>
-#include <linux/gfp.h>
#include <asm-xen/evtchn.h>
-#if 0
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#include <linux/devfs_fs_kernel.h>
+#define OLD_DEVFS
+#else
+#include <linux/gfp.h>
+#endif
+
+#ifdef OLD_DEVFS
/* NB. This must be shared amongst drivers if more things go in /dev/xen */
static devfs_handle_t xen_dev_dir;
#endif
void evtchn_device_upcall(int port)
{
-
spin_lock(&lock);
mask_evtchn(port);
};
static struct miscdevice evtchn_miscdev = {
- .minor = EVTCHN_MINOR,
- .name = "evtchn",
- .devfs_name = "misc/evtchn",
- .fops = &evtchn_fops
+ .minor = EVTCHN_MINOR,
+ .name = "evtchn",
+ .fops = &evtchn_fops,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ .devfs_name = "misc/evtchn",
+#endif
};
static int __init evtchn_init(void)
{
-#if 0
+#ifdef OLD_DEVFS
devfs_handle_t symlink_handle;
- int err, pos;
+ int pos;
char link_dest[64];
#endif
int err;
return err;
}
-#if 0
+#ifdef OLD_DEVFS
/* (DEVFS) create directory '/dev/xen'. */
xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL);
#include <asm/io.h>
#include <asm/pgalloc.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define irqreturn_t void
-#define IRQ_HANDLED
-#endif
-
#if 0
#define ASSERT(_p) \
if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
#include <asm-xen/hypervisor-ifs/io/netif.h>
#include <asm/page.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define irqreturn_t void
-#define IRQ_HANDLED
-#endif
-
#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */
static void network_tx_buf_gc(struct net_device *dev);
+++ /dev/null
-/******************************************************************************
- * hypervisor.h
- *
- * Linux-specific hypervisor handling.
- *
- * Copyright (c) 2002, K A Fraser
- */
-
-#ifndef __HYPERVISOR_H__
-#define __HYPERVISOR_H__
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <asm/hypervisor-ifs/hypervisor-if.h>
-#include <asm/hypervisor-ifs/dom0_ops.h>
-#include <asm/hypervisor-ifs/io/domain_controller.h>
-#include <asm/ptrace.h>
-#include <asm/page.h>
-#include <asm-xen/xen.h>
-
-/* arch/xen/i386/kernel/setup.c */
-union start_info_union
-{
- extended_start_info_t start_info;
- char padding[512];
-};
-extern union start_info_union start_info_union;
-#define start_info (start_info_union.start_info)
-
-/* arch/xen/i386/kernel/hypervisor.c */
-void do_hypervisor_callback(struct pt_regs *regs);
-
-/* arch/xen/i386/mm/init.c */
-void wrprotect_bootpt(pgd_t *, void *, int);
-
-/* arch/xen/i386/kernel/head.S */
-void lgdt_finish(void);
-
-/* arch/xen/i386/mm/hypervisor.c */
-/*
- * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
- * be MACHINE addresses.
- */
-
-extern unsigned int mmu_update_queue_idx;
-
-void queue_l1_entry_update(pte_t *ptr, unsigned long val);
-void queue_l2_entry_update(pmd_t *ptr, unsigned long val);
-void queue_pt_switch(unsigned long ptr);
-void queue_tlb_flush(void);
-void queue_invlpg(unsigned long ptr);
-void queue_pgd_pin(unsigned long ptr);
-void queue_pgd_unpin(unsigned long ptr);
-void queue_pte_pin(unsigned long ptr);
-void queue_pte_unpin(unsigned long ptr);
-void queue_set_ldt(unsigned long ptr, unsigned long bytes);
-void queue_machphys_update(unsigned long mfn, unsigned long pfn);
-#define MMU_UPDATE_DEBUG 0
-
-#if MMU_UPDATE_DEBUG > 0
-typedef struct {
- void *ptr;
- unsigned long val, pteval;
- void *ptep;
- int line; char *file;
-} page_update_debug_t;
-extern page_update_debug_t update_debug_queue[];
-#define queue_l1_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- queue_l1_entry_update((_p),(_v)); \
-})
-#define queue_l2_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- queue_l2_entry_update((_p),(_v)); \
-})
-#endif
-
-#if MMU_UPDATE_DEBUG > 1
-#if MMU_UPDATE_DEBUG > 2
-#undef queue_l1_entry_update
-#define queue_l1_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- printk("L1 %s %d: %p/%08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p), virt_to_machine(_p), pte_val(*(_p)), \
- (unsigned long)(_v)); \
- queue_l1_entry_update((_p),(_v)); \
-})
-#endif
-#undef queue_l2_entry_update
-#define queue_l2_entry_update(_p,_v) ({ \
- update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
- update_debug_queue[mmu_update_queue_idx].val = (_v); \
- update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
- update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
- printk("L2 %s %d: %p/%08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p), virt_to_machine(_p), pmd_val(*_p), \
- (unsigned long)(_v)); \
- queue_l2_entry_update((_p),(_v)); \
-})
-#define queue_pt_switch(_p) ({ \
- printk("PTSWITCH %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pt_switch(_p); \
-})
-#define queue_tlb_flush() ({ \
- printk("TLB FLUSH %s %d\n", __FILE__, __LINE__); \
- queue_tlb_flush(); \
-})
-#define queue_invlpg(_p) ({ \
- printk("INVLPG %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_invlpg(_p); \
-})
-#define queue_pgd_pin(_p) ({ \
- printk("PGD PIN %s %d: %08lx/%08lx\n", __FILE__, __LINE__, (_p), \
- phys_to_machine(_p)); \
- queue_pgd_pin(_p); \
-})
-#define queue_pgd_unpin(_p) ({ \
- printk("PGD UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pgd_unpin(_p); \
-})
-#define queue_pte_pin(_p) ({ \
- printk("PTE PIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pte_pin(_p); \
-})
-#define queue_pte_unpin(_p) ({ \
- printk("PTE UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
- queue_pte_unpin(_p); \
-})
-#define queue_set_ldt(_p,_l) ({ \
- printk("SETL LDT %s %d: %08lx %d\n", __FILE__, __LINE__, (_p), (_l)); \
- queue_set_ldt((_p), (_l)); \
-})
-#endif
-
-void _flush_page_update_queue(void);
-static inline int flush_page_update_queue(void)
-{
- unsigned int idx = mmu_update_queue_idx;
- if ( idx != 0 ) _flush_page_update_queue();
- return idx;
-}
-#define xen_flush_page_update_queue() (_flush_page_update_queue())
-void MULTICALL_flush_page_update_queue(void);
-
-#ifdef CONFIG_XEN_PHYSDEV_ACCESS
-/* Allocate a contiguous empty region of low memory. Return virtual start. */
-unsigned long allocate_empty_lowmem_region(unsigned long pages);
-/* Deallocate a contiguous region of low memory. Return it to the allocator. */
-void deallocate_lowmem_region(unsigned long vstart, unsigned long pages);
-#endif
-
-/*
- * Assembler stubs for hyper-calls.
- */
-
-static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
- "b" (table) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_mmu_update(mmu_update_t *req, int count,
- int *success_count)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
- "b" (req), "c" (count), "d" (success_count) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_gdt),
- "b" (frame_list), "c" (entries) : "memory" );
-
-
- return ret;
-}
-
-static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_stack_switch),
- "b" (ss), "c" (esp) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_callbacks(
- unsigned long event_selector, unsigned long event_address,
- unsigned long failsafe_selector, unsigned long failsafe_address)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
- "b" (event_selector), "c" (event_address),
- "d" (failsafe_selector), "S" (failsafe_address) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_fpu_taskswitch(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_yield(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_yield) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_block(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_block) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_shutdown(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
- : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_reboot(void)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
- : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_suspend(unsigned long srec)
-{
- int ret;
- /* NB. On suspend, control software expects a suspend record in %esi. */
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
- "S" (srec) : "memory" );
-
- return ret;
-}
-
-static inline long HYPERVISOR_set_timer_op(u64 timeout)
-{
- int ret;
- unsigned long timeout_hi = (unsigned long)(timeout>>32);
- unsigned long timeout_lo = (unsigned long)timeout;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op),
- "b" (timeout_hi), "c" (timeout_lo) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
-{
- int ret;
- dom0_op->interface_version = DOM0_INTERFACE_VERSION;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
- "b" (dom0_op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg),
- "b" (reg), "c" (value) : "memory" );
-
- return ret;
-}
-
-static inline unsigned long HYPERVISOR_get_debugreg(int reg)
-{
- unsigned long ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg),
- "b" (reg) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_descriptor(
- unsigned long ma, unsigned long word1, unsigned long word2)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor),
- "b" (ma), "c" (word1), "d" (word2) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_set_fast_trap(int idx)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap),
- "b" (idx) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_dom_mem_op(unsigned int op,
- unsigned long *pages,
- unsigned long nr_pages)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
- "b" (op), "c" (pages), "d" (nr_pages) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_multicall),
- "b" (call_list), "c" (nr_calls) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_va_mapping(
- unsigned long page_nr, pte_t new_val, unsigned long flags)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping),
- "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) : "memory" );
-
- if ( unlikely(ret < 0) )
- {
- printk(KERN_ALERT "Failed update VA mapping: %08lx, %08lx, %08lx\n",
- page_nr, (new_val).pte_low, flags);
- BUG();
- }
-
- return ret;
-}
-
-static inline int HYPERVISOR_event_channel_op(void *op)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_event_channel_op),
- "b" (op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_xen_version(int cmd)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_xen_version),
- "b" (cmd) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_console_io),
- "b" (cmd), "c" (count), "d" (str) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_physdev_op(void *physdev_op)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_physdev_op),
- "b" (physdev_op) : "memory" );
-
- return ret;
-}
-
-static inline int HYPERVISOR_update_va_mapping_otherdomain(
- unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
-{
- int ret;
- __asm__ __volatile__ (
- TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
- "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) :
- "memory" );
-
- return ret;
-}
-
-#endif /* __HYPERVISOR_H__ */
#define __ASM_MSR_H
#include <linux/smp.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
/*
* Access to machine-specific registers (available on 586 and better only)
#define _I386_PGTABLE_H
#include <linux/config.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
/*
* The Linux memory management assumes a three-level page table setup. On
#include <asm/synch_bitops.h>
#include <asm/segment.h>
#include <asm/cpufeature.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
#include <asm-xen/evtchn.h>
#ifdef __KERNEL__
#ifndef __ASM_XEN__CTRL_IF_H__
#define __ASM_XEN__CTRL_IF_H__
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#include <linux/tqueue.h>
+#define work_struct tq_struct
+#endif
typedef control_msg_t ctrl_msg_t;
#define __ASM_EVTCHN_H__
#include <linux/config.h>
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
#include <asm/ptrace.h>
#include <asm/synch_bitops.h>
#include <asm/hypervisor-ifs/event_channel.h>
--- /dev/null
+/******************************************************************************
+ * hypervisor.h
+ *
+ * Linux-specific hypervisor handling.
+ *
+ * Copyright (c) 2002, K A Fraser
+ */
+
+#ifndef __HYPERVISOR_H__
+#define __HYPERVISOR_H__
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <asm/hypervisor-ifs/hypervisor-if.h>
+#include <asm/hypervisor-ifs/dom0_ops.h>
+#include <asm/hypervisor-ifs/io/domain_controller.h>
+#include <asm/ptrace.h>
+#include <asm/page.h>
+
+/* arch/xen/i386/kernel/setup.c */
+union start_info_union
+{
+ extended_start_info_t start_info;
+ char padding[512];
+};
+extern union start_info_union start_info_union;
+#define start_info (start_info_union.start_info)
+
+/* arch/xen/kernel/process.c */
+void xen_cpu_idle (void);
+
+/* arch/xen/i386/kernel/hypervisor.c */
+void do_hypervisor_callback(struct pt_regs *regs);
+
+/* arch/xen/i386/mm/init.c */
+void wrprotect_bootpt(pgd_t *, void *, int);
+
+/* arch/xen/i386/kernel/head.S */
+void lgdt_finish(void);
+
+/* arch/xen/i386/mm/hypervisor.c */
+/*
+ * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
+ * be MACHINE addresses.
+ */
+
+extern unsigned int mmu_update_queue_idx;
+
+void queue_l1_entry_update(pte_t *ptr, unsigned long val);
+void queue_l2_entry_update(pmd_t *ptr, unsigned long val);
+void queue_pt_switch(unsigned long ptr);
+void queue_tlb_flush(void);
+void queue_invlpg(unsigned long ptr);
+void queue_pgd_pin(unsigned long ptr);
+void queue_pgd_unpin(unsigned long ptr);
+void queue_pte_pin(unsigned long ptr);
+void queue_pte_unpin(unsigned long ptr);
+void queue_set_ldt(unsigned long ptr, unsigned long bytes);
+void queue_machphys_update(unsigned long mfn, unsigned long pfn);
+#define MMU_UPDATE_DEBUG 0
+
+#if MMU_UPDATE_DEBUG > 0
+typedef struct {
+ void *ptr;
+ unsigned long val, pteval;
+ void *ptep;
+ int line; char *file;
+} page_update_debug_t;
+extern page_update_debug_t update_debug_queue[];
+#define queue_l1_entry_update(_p,_v) ({ \
+ update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
+ update_debug_queue[mmu_update_queue_idx].val = (_v); \
+ update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
+ update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
+ queue_l1_entry_update((_p),(_v)); \
+})
+#define queue_l2_entry_update(_p,_v) ({ \
+ update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
+ update_debug_queue[mmu_update_queue_idx].val = (_v); \
+ update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
+ update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
+ queue_l2_entry_update((_p),(_v)); \
+})
+#endif
+
+#if MMU_UPDATE_DEBUG > 1
+#if MMU_UPDATE_DEBUG > 2
+#undef queue_l1_entry_update
+#define queue_l1_entry_update(_p,_v) ({ \
+ update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
+ update_debug_queue[mmu_update_queue_idx].val = (_v); \
+ update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
+ update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
+ printk("L1 %s %d: %p/%08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
+ (_p), virt_to_machine(_p), pte_val(*(_p)), \
+ (unsigned long)(_v)); \
+ queue_l1_entry_update((_p),(_v)); \
+})
+#endif
+#undef queue_l2_entry_update
+#define queue_l2_entry_update(_p,_v) ({ \
+ update_debug_queue[mmu_update_queue_idx].ptr = (_p); \
+ update_debug_queue[mmu_update_queue_idx].val = (_v); \
+ update_debug_queue[mmu_update_queue_idx].line = __LINE__; \
+ update_debug_queue[mmu_update_queue_idx].file = __FILE__; \
+ printk("L2 %s %d: %p/%08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
+ (_p), virt_to_machine(_p), pmd_val(*_p), \
+ (unsigned long)(_v)); \
+ queue_l2_entry_update((_p),(_v)); \
+})
+#define queue_pt_switch(_p) ({ \
+ printk("PTSWITCH %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
+ queue_pt_switch(_p); \
+})
+#define queue_tlb_flush() ({ \
+ printk("TLB FLUSH %s %d\n", __FILE__, __LINE__); \
+ queue_tlb_flush(); \
+})
+#define queue_invlpg(_p) ({ \
+ printk("INVLPG %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
+ queue_invlpg(_p); \
+})
+#define queue_pgd_pin(_p) ({ \
+ printk("PGD PIN %s %d: %08lx/%08lx\n", __FILE__, __LINE__, (_p), \
+ phys_to_machine(_p)); \
+ queue_pgd_pin(_p); \
+})
+#define queue_pgd_unpin(_p) ({ \
+ printk("PGD UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
+ queue_pgd_unpin(_p); \
+})
+#define queue_pte_pin(_p) ({ \
+ printk("PTE PIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
+ queue_pte_pin(_p); \
+})
+#define queue_pte_unpin(_p) ({ \
+ printk("PTE UNPIN %s %d: %08lx\n", __FILE__, __LINE__, (_p)); \
+ queue_pte_unpin(_p); \
+})
+#define queue_set_ldt(_p,_l) ({ \
+ printk("SETL LDT %s %d: %08lx %d\n", __FILE__, __LINE__, (_p), (_l)); \
+ queue_set_ldt((_p), (_l)); \
+})
+#endif
+
+void _flush_page_update_queue(void);
+static inline int flush_page_update_queue(void)
+{
+ unsigned int idx = mmu_update_queue_idx;
+ if ( idx != 0 ) _flush_page_update_queue();
+ return idx;
+}
+#define xen_flush_page_update_queue() (_flush_page_update_queue())
+#define XEN_flush_page_update_queue() (_flush_page_update_queue())
+void MULTICALL_flush_page_update_queue(void);
+
+#ifdef CONFIG_XEN_PHYSDEV_ACCESS
+/* Allocate a contiguous empty region of low memory. Return virtual start. */
+unsigned long allocate_empty_lowmem_region(unsigned long pages);
+/* Deallocate a contiguous region of low memory. Return it to the allocator. */
+void deallocate_lowmem_region(unsigned long vstart, unsigned long pages);
+#endif
+
+/*
+ * Assembler stubs for hyper-calls.
+ */
+
+static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
+ "b" (table) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_mmu_update(mmu_update_t *req, int count,
+ int *success_count)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
+ "b" (req), "c" (count), "d" (success_count) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_gdt),
+ "b" (frame_list), "c" (entries) : "memory" );
+
+
+ return ret;
+}
+
+static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_stack_switch),
+ "b" (ss), "c" (esp) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_set_callbacks(
+ unsigned long event_selector, unsigned long event_address,
+ unsigned long failsafe_selector, unsigned long failsafe_address)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
+ "b" (event_selector), "c" (event_address),
+ "d" (failsafe_selector), "S" (failsafe_address) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_fpu_taskswitch(void)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_yield(void)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+ "b" (SCHEDOP_yield) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_block(void)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+ "b" (SCHEDOP_block) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_shutdown(void)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+ "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
+ : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_reboot(void)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+ "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
+ : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_suspend(unsigned long srec)
+{
+ int ret;
+ /* NB. On suspend, control software expects a suspend record in %esi. */
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
+ "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
+ "S" (srec) : "memory" );
+
+ return ret;
+}
+
+static inline long HYPERVISOR_set_timer_op(u64 timeout)
+{
+ int ret;
+ unsigned long timeout_hi = (unsigned long)(timeout>>32);
+ unsigned long timeout_lo = (unsigned long)timeout;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op),
+ "b" (timeout_hi), "c" (timeout_lo) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
+{
+ int ret;
+ dom0_op->interface_version = DOM0_INTERFACE_VERSION;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
+ "b" (dom0_op) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg),
+ "b" (reg), "c" (value) : "memory" );
+
+ return ret;
+}
+
+static inline unsigned long HYPERVISOR_get_debugreg(int reg)
+{
+ unsigned long ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg),
+ "b" (reg) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_update_descriptor(
+ unsigned long ma, unsigned long word1, unsigned long word2)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor),
+ "b" (ma), "c" (word1), "d" (word2) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_set_fast_trap(int idx)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap),
+ "b" (idx) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_dom_mem_op(unsigned int op,
+ unsigned long *pages,
+ unsigned long nr_pages)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
+ "b" (op), "c" (pages), "d" (nr_pages) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_multicall),
+ "b" (call_list), "c" (nr_calls) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_update_va_mapping(
+ unsigned long page_nr, pte_t new_val, unsigned long flags)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping),
+ "b" (page_nr), "c" ((new_val).pte_low), "d" (flags) : "memory" );
+
+ if ( unlikely(ret < 0) )
+ {
+ printk(KERN_ALERT "Failed update VA mapping: %08lx, %08lx, %08lx\n",
+ page_nr, (new_val).pte_low, flags);
+ BUG();
+ }
+
+ return ret;
+}
+
+static inline int HYPERVISOR_event_channel_op(void *op)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_event_channel_op),
+ "b" (op) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_xen_version(int cmd)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_xen_version),
+ "b" (cmd) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_console_io),
+ "b" (cmd), "c" (count), "d" (str) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_physdev_op(void *physdev_op)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_physdev_op),
+ "b" (physdev_op) : "memory" );
+
+ return ret;
+}
+
+static inline int HYPERVISOR_update_va_mapping_otherdomain(
+ unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
+ "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) :
+ "memory" );
+
+ return ret;
+}
+
+#endif /* __HYPERVISOR_H__ */
#ifndef __MULTICALL_H__
#define __MULTICALL_H__
-#include <asm/hypervisor.h>
+#include <asm-xen/hypervisor.h>
extern multicall_entry_t multicall_list[];
extern int nr_multicall_ents;
--- /dev/null
+/******************************************************************************
+ * suspend.h
+ *
+ * NB. This file is part of the Xenolinux interface with Xenoserver control
+ * software. It can be included in such software without invoking the GPL.
+ *
+ * Copyright (c) 2003, K A Fraser
+ */
+
+#ifndef __ASM_XEN_SUSPEND_H__
+#define __ASM_XEN_SUSPEND_H__
+
+typedef struct suspend_record_st {
+ /* To be filled in before resume. */
+ extended_start_info_t resume_info;
+ /*
+ * The number of a machine frame containing, in sequence, the number of
+ * each machine frame that contains PFN -> MFN translation table data.
+ */
+ unsigned long pfn_to_mfn_frame_list;
+ /* Number of entries in the PFN -> MFN translation table. */
+ unsigned long nr_pfns;
+} suspend_record_t;
+
+#endif /* __ASM_XEN_SUSPEND_H__ */
+++ /dev/null
-
-/* arch/xen/kernel/process.c */
-void xen_cpu_idle (void);
*
* Code to handle memory related requests from domains eg. balloon driver.
*
- * Copyright (c) 2003, B Dragovic & K A Fraser.
+ * Copyright (c) 2003-2004, B Dragovic & K A Fraser.
*/
#include <xen/config.h>